110 lines
2.5 KiB
C
110 lines
2.5 KiB
C
|
//
|
||
|
// auto_rel.h
|
||
|
//
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
// class I - Multi-Inheritance casting for ATL type classes
|
||
|
// ergo C2385 - T::Release() is ambiguous
|
||
|
//
|
||
|
template<class T, class I = T>
|
||
|
class auto_rel
|
||
|
{
|
||
|
public:
|
||
|
explicit auto_rel(T* p = 0)
|
||
|
: pointee(p) {};
|
||
|
// Don't AddRef()
|
||
|
|
||
|
auto_rel(auto_rel<T,I>& rhs)
|
||
|
: pointee(rhs.get()) { if (pointee) ((I*)pointee)->AddRef(); }
|
||
|
|
||
|
~auto_rel()
|
||
|
{
|
||
|
if (pointee)
|
||
|
((I*)pointee)->Release();
|
||
|
};
|
||
|
|
||
|
auto_rel<T,I>& operator= (const auto_rel<T,I>& rhs)
|
||
|
{
|
||
|
if (this != rhs.getThis())
|
||
|
{
|
||
|
reset (rhs.get());
|
||
|
if (pointee) ((I*)pointee)->AddRef();
|
||
|
}
|
||
|
return *this;
|
||
|
};
|
||
|
|
||
|
auto_rel<T,I>& operator= (T*rhs)
|
||
|
{
|
||
|
reset (rhs);
|
||
|
// Don't AddRef()
|
||
|
return *this;
|
||
|
};
|
||
|
|
||
|
T& operator*() const
|
||
|
{ return *pointee; };
|
||
|
T* operator-> () const
|
||
|
{ return pointee; };
|
||
|
T** operator& () // for OpenEntry etc...
|
||
|
{ reset(); return &pointee; };
|
||
|
operator T* ()
|
||
|
{ return pointee; };
|
||
|
#ifdef MAPIDEFS_H
|
||
|
operator LPMAPIPROP ()
|
||
|
{ return (LPMAPIPROP)pointee; };
|
||
|
#endif
|
||
|
operator bool ()
|
||
|
{ return pointee != NULL; };
|
||
|
operator bool () const
|
||
|
{ return pointee != NULL; };
|
||
|
bool operator! ()
|
||
|
{ return pointee == NULL; };
|
||
|
bool operator! () const
|
||
|
{ return pointee == NULL; };
|
||
|
|
||
|
// Checks for NULL
|
||
|
bool operator== (LPVOID lpv)
|
||
|
{ return pointee == lpv; };
|
||
|
bool operator!= (LPVOID lpv)
|
||
|
{ return pointee != lpv; };
|
||
|
bool operator== (const auto_rel<T,I>& rhs)
|
||
|
{ return pointee == rhs.pointee; }
|
||
|
bool operator< (const auto_rel<T,I>& rhs)
|
||
|
{ return pointee < rhs.pointee; }
|
||
|
|
||
|
// return value of current dumb pointer
|
||
|
T* get() const
|
||
|
{ return pointee; };
|
||
|
|
||
|
// relinquish ownership
|
||
|
T* release()
|
||
|
{ T * oldPointee = pointee;
|
||
|
pointee = 0;
|
||
|
return oldPointee;
|
||
|
};
|
||
|
|
||
|
// delete owned pointer; assume ownership of p
|
||
|
ULONG reset (T* p = 0)
|
||
|
{ ULONG ul = 0;
|
||
|
if (pointee)
|
||
|
ul = ((I*)pointee)->Release();
|
||
|
pointee = p;
|
||
|
|
||
|
return ul;
|
||
|
};
|
||
|
|
||
|
private:
|
||
|
#ifdef MAPIDEFS_H
|
||
|
// these are here on purpose, better to find out at compile time
|
||
|
// use auto_padr<T,I> or auto_prow<T,I>
|
||
|
operator LPADRLIST () { return 0; };
|
||
|
operator LPSRowSet () { return 0; };
|
||
|
#endif
|
||
|
|
||
|
// operator& throws off operator=
|
||
|
const auto_rel<T,I> * getThis() const
|
||
|
{ return this; };
|
||
|
|
||
|
T* pointee;
|
||
|
};
|