Files
firestorm/Gameleap/code/mw4/Libraries/stuff/Auto_Ptr.hpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

293 lines
5.2 KiB
C++

#pragma once
#ifndef Auto_Ptr_HPP
#define Auto_Ptr_HPP
#include "Stuff.hpp"
namespace Stuff
{
// Auto_Ptr<>: similar to the STL auto_ptr<> class, but better! :)
// An Auto_Ptr<> is a pointer that "owns" the object pointed to.
// When the Auto_Ptr<> is deleted, it will also delete the object
// if it still owns the pointer. Auto_Ptr<> also handles the transfer
// of ownership between Auto_Ptrs via the == operators.
// This version of Auto_Ptr<> is slightly more memory-efficient as it
// stores the ownership bits in the unused bits of the pointer data member.
// It also allows you to specify whether or not to use array deletion;
// this also is stored in the extra bits of the pointer.
template <class T>
class Auto_Ptr
{
public:
Auto_Ptr();
explicit Auto_Ptr(T* ptr, bool delete_as_array = DELETE_NORMAL);
Auto_Ptr(Auto_Ptr const& src);
~Auto_Ptr();
enum deletion_type
{
DELETE_AS_ARRAY = true,
DELETE_NORMAL = false
};
Auto_Ptr<T> Assimilate(T* ptr, bool delete_as_array = DELETE_NORMAL);
Auto_Ptr<T> Assimilate(Auto_Ptr<T>& src);
T* GetPointer() const;
T* Release() const;
T* ReleaseAndNull();
Auto_Ptr<T>& operator=(Auto_Ptr<T> const& src);
operator bool() const;
T& operator*() const;
T* operator->() const;
void Swap(Auto_Ptr<T>& src);
void Delete();
private:
bool IsOwner() const;
bool IsArray() const;
void SetAsOwner(bool fOwn) const;
void SetAsArray(bool fArray);
void Set(T* ptr, bool fIsOwner, bool fIsArray);
mutable union
{
T *m_ptr;
mutable int unsigned m_bits;
};
enum
{
OWNER_MASK = 1,
ARRAY_MASK = 2,
POINTER_MASK = ~3
};
};
template<class T>
inline bool operator==(const Auto_Ptr<T>& a,
const Auto_Ptr<T>& b)
{
return (a.GetPointer() == b.GetPointer());
}
template<class T>
inline bool operator==(const T* a,
const Auto_Ptr<T>& b)
{
return (a == b.GetPointer());
}
template<class T>
inline bool operator==(const Auto_Ptr<T>& a,
const T* b)
{
return (a.GetPointer() == b);
}
}; // namespace Stuff
template <class T>
Stuff::Auto_Ptr<T>::Auto_Ptr()
: m_ptr(0)
{
Verify(sizeof(T*) == sizeof(unsigned int));
}
template <class T>
Stuff::Auto_Ptr<T>::Auto_Ptr(T* ptr, bool delete_as_array)
{
Verify(sizeof(T *) == sizeof(unsigned int));
Set(ptr,true,delete_as_array);
}
template <class T>
Stuff::Auto_Ptr<T>::Auto_Ptr(Auto_Ptr const& src)
{
Verify(sizeof(T*) == sizeof(unsigned int));
m_ptr = src.m_ptr;
src.SetAsOwner(false);
}
template <class T>
Stuff::Auto_Ptr<T>::~Auto_Ptr()
{
Delete();
}
template <class T>
Stuff::Auto_Ptr<T> Stuff::Auto_Ptr<T>::Assimilate(T* ptr, bool delete_as_array)
{
Auto_Ptr<T> temp(*this);
Set(ptr,true,delete_as_array);
return (temp);
}
template <class T>
Stuff::Auto_Ptr<T> Stuff::Auto_Ptr<T>::Assimilate(Auto_Ptr<T>& src)
{
Auto_Ptr<T> temp;
if (&src != this)
{
temp = *this;
m_ptr = src.m_ptr;
src.SetAsOwner(false);
}
return (temp);
}
template <class T>
T* Stuff::Auto_Ptr<T>::GetPointer() const
{
return ((T*)(m_bits & POINTER_MASK));
}
template <class T>
T* Stuff::Auto_Ptr<T>::Release() const
{
SetAsOwner(false);
return (GetPointer());
}
template <class T>
T* Stuff::Auto_Ptr<T>::ReleaseAndNull()
{
T* rv = GetPointer();
m_ptr = 0;
return (rv);
}
template <class T>
Stuff::Auto_Ptr<T>& Stuff::Auto_Ptr<T>::operator=(Auto_Ptr<T> const& src)
{
if (&src != this)
{
Delete();
m_ptr = src.m_ptr;
src.SetAsOwner(false);
}
return (*this);
}
template <class T>
Stuff::Auto_Ptr<T>::operator bool() const
{
return (GetPointer() != 0);
}
template <class T>
T& Stuff::Auto_Ptr<T>::operator*() const
{
return (*GetPointer());
}
template <class T>
T* Stuff::Auto_Ptr<T>::operator->() const
{
return (GetPointer());
}
template <class T>
void Stuff::Auto_Ptr<T>::Swap(Auto_Ptr<T>& src)
{
if (this != &src)
{
T* temp_ptr = src.m_ptr;
src.m_ptr = m_ptr;
m_ptr = temp_ptr;
}
}
template <class T>
void Stuff::Auto_Ptr<T>::Delete()
{
if (IsOwner())
{
if (IsArray())
{
m_bits &= POINTER_MASK;
delete [] m_ptr;
}
else
{
m_bits &= POINTER_MASK;
delete m_ptr;
}
}
m_ptr = 0;
}
template <class T>
bool Stuff::Auto_Ptr<T>::IsOwner() const
{
return ((m_bits & OWNER_MASK) == OWNER_MASK);
}
template <class T>
bool Stuff::Auto_Ptr<T>::IsArray() const
{
return ((m_bits & ARRAY_MASK) == ARRAY_MASK);
}
template <class T>
void Stuff::Auto_Ptr<T>::SetAsOwner(bool fOwn) const
{
if (fOwn == true)
{
m_bits |= OWNER_MASK;
}
else
{
m_bits &= ~OWNER_MASK;
}
}
template <class T>
void Stuff::Auto_Ptr<T>::SetAsArray(bool fArray)
{
if (fArray == true)
{
m_bits |= ARRAY_MASK;
}
else
{
m_bits &= ~ARRAY_MASK;
}
}
template <class T>
void Stuff::Auto_Ptr<T>::Set(T* ptr, bool fIsOwner, bool fIsArray)
{
m_ptr = ptr;
Verify((m_bits & POINTER_MASK) == m_bits);
if (fIsOwner == true)
{
m_bits |= OWNER_MASK;
}
if (fIsArray == true)
{
m_bits |= ARRAY_MASK;
}
}
#endif // Auto_Ptr_HPP