windows-nt/Source/XPSP1/NT/shell/osshell/dskquota/common/autoptr.h
2020-09-26 16:20:57 +08:00

246 lines
4.2 KiB
C++

#ifndef _INC_DSKQUOTA_AUTOPTR_H
#define _INC_DSKQUOTA_AUTOPTR_H
///////////////////////////////////////////////////////////////////////////////
/* File: autoptr.h
Description: Template auto pointer classes to support normal C++ pointers
as well as shell and COM object pointers.
This code was created by DavePl for the Entertainment Center project.
It worked very well so I've "borrowed" it (thanks Dave). I think his
original implementation borrowed from the STL implementation.
Revision History:
Date Description Programmer
-------- --------------------------------------------------- ----------
07/01/97 Initial creation. BrianAu
*/
///////////////////////////////////////////////////////////////////////////////
// a_ptr
//
// Safe pointer class that knows to delete the referrent object when
// the pointer goes out of scope or is replaced, etc.
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning(disable:4284)
template<class _TYPE> class a_ptr
{
public:
typedef _TYPE element_type;
a_ptr(_TYPE *_P = 0)
: _Owns(_P != 0), _Ptr(_P)
{}
typedef _TYPE _U;
a_ptr(const a_ptr<_U>& _Y) : _Owns(_Y._Owns), _Ptr((_TYPE *)_Y.disown())
{}
virtual void nukeit() = 0
{
}
a_ptr<_TYPE>& operator=(const a_ptr<_U>& _Y)
{
if ((void *)this != (void *)&_Y)
{
if (_Owns)
nukeit();
_Owns = _Y._Owns;
_Ptr = (_TYPE *)_Y.disown();
// ASSERT( !_Owns || _Ptr );
}
return (*this);
}
a_ptr<_TYPE>& replace(const a_ptr<_U>& _Y)
{
return *this = _Y;
}
virtual ~a_ptr()
{
}
operator _TYPE*()
{
return get();
}
operator const _TYPE*() const
{
return get();
}
_TYPE& operator*() const
{
return (*get());
}
_TYPE *operator->() const
{
return (get());
}
_TYPE *get() const
{
return (_Ptr);
}
_TYPE *disown() const
{
((a_ptr<_TYPE> *)this)->_Owns = FALSE;
return (_Ptr);
}
_TYPE ** getaddr()
{
*this = (_TYPE *) NULL;
_Owns = TRUE;
return (&_Ptr);
}
protected:
BOOL _Owns;
_TYPE *_Ptr;
};
#if _MSC_VER >= 1200
#pragma warning(pop)
#else
#pragma warning(default:4284)
#endif
// autoptr
//
template<class _TYPE>
class autoptr : public a_ptr<_TYPE>
{
virtual void nukeit()
{
delete _Ptr;
}
public:
~autoptr()
{
if (_Owns)
this->nukeit();
}
autoptr(_TYPE *_P = 0)
: a_ptr<_TYPE>(_P)
{
}
};
template<class _TYPE>
class array_autoptr : public a_ptr<_TYPE>
{
virtual void nukeit()
{
if (_Ptr)
delete[] _Ptr;
}
public:
~array_autoptr()
{
if (_Owns)
this->nukeit();
}
array_autoptr(_TYPE *_P = 0)
: a_ptr<_TYPE>(_P)
{
}
};
// sh_autoptr
//
// Smart pointer that manually runs the referent's destructor and then
// calls the shell's task allocator to free the object's memory footprint
template<class _TYPE>
class sh_autoptr : virtual public a_ptr<_TYPE>
{
virtual void nukeit()
{
if (_Ptr)
{
IMalloc *pMalloc;
_Ptr->~_TYPE();
if (SUCCEEDED(SHGetMalloc(&pMalloc)))
{
pMalloc->Free(_Ptr);
pMalloc->Release();
}
}
}
public:
~sh_autoptr()
{
if (_Owns)
this->nukeit();
}
sh_autoptr(_TYPE *_P = 0)
: a_ptr<_TYPE>(_P)
{
}
};
// com_autoptr (nothing to do with ole automation... its an automatic ole ptr)
//
// Smart pointer that calls disown() on the referent when the pointer itself
// goes out of scope
template<class _TYPE>
class com_autoptr : public a_ptr<_TYPE>
{
virtual void nukeit()
{
if (_Ptr)
_Ptr->Release();
}
public:
~com_autoptr()
{
if (_Owns)
this->nukeit();
}
com_autoptr(_TYPE *_P = 0)
: a_ptr<_TYPE>(_P)
{
}
};
#endif // _INC_DSKQUOTA_AUTOPTR_H