diff options
| author | Konstantin <const@const.me> | 2023-01-16 14:52:43 +0100 |
|---|---|---|
| committer | Konstantin <const@const.me> | 2023-01-16 14:52:43 +0100 |
| commit | 8c4603c73675958efc960fbd4bb599a2909d106a (patch) | |
| tree | 714dc6fc9a1672d5fd7f89676b97e10959662abc /ComLightLib/client | |
| parent | 990a8d0dbaefc996244097397259e92758b15cce (diff) | |
Source codes
Diffstat (limited to 'ComLightLib/client')
| -rw-r--r-- | ComLightLib/client/CComPtr.hpp | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/ComLightLib/client/CComPtr.hpp b/ComLightLib/client/CComPtr.hpp new file mode 100644 index 0000000..7786591 --- /dev/null +++ b/ComLightLib/client/CComPtr.hpp @@ -0,0 +1,110 @@ +#pragma once + +namespace ComLight +{ + // COM smart pointer, very comparable to CComPtr from ATL + template <class I> + class CComPtr + { + I* p; + + void callAddRef() const + { + if( nullptr == p ) + return; + p->AddRef(); + } + + public: + + // Construct with nullptr + CComPtr() : p( nullptr ) { } + + // Release the pointer + void release() + { + if( nullptr == p ) + return; + p->Release(); + p = nullptr; + } + + ~CComPtr() + { + release(); + } + + // Attach without AddRef() + void attach( I* raw ) + { + release(); + p = raw; + } + + // Detach without Release(), set this pointer to nullptr + I* detach() + { + I* const result = p; + p = nullptr; + return result; + } + + // Detach without Release() and place to the specified address, set this pointer to nullptr + template<class Other> + void detach( Other** pp ) + { + // If the argument points to a non-empty object, release the old instance: would leak memory otherwise. + if( nullptr != *pp ) + ( *pp )->Release(); + ( *pp ) = detach(); + } + + // Set and AddRef() + void assign( I* raw ) + { + release(); + attach( raw ); + callAddRef(); + } + + void swap( CComPtr<I>& that ) + { + std::swap( p, that.p ); + } + + // Set and AddRef() + CComPtr( I* raw ) : p( raw ) + { + callAddRef(); + } + + // Set and AddRef() + CComPtr( const CComPtr<I>& that ) : CComPtr( that.p ) { } + // Move constructor + CComPtr( CComPtr<I>&& that ) : p( that.p ) { that.p = nullptr; } + + // Set and AddRef() + void operator=( I* raw ) + { + assign( raw ); + } + + // Set and AddRef() + void operator=( const CComPtr<I>& that ) + { + assign( that.p ); + } + + // Move assignment operator, destroys the other one + void operator=( CComPtr<I>&& that ) + { + attach( that.detach() ); + } + + operator I*( ) const { return p; } + I* operator -> () const { return p; } + I** operator &() { return &p; } + + operator bool() const { return nullptr != p; } + }; +}
\ No newline at end of file |
