Created
October 19, 2015 00:53
-
-
Save dranger003/6abaab935bfd01fc9000 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// RefObj.h : includes CRefObject, CRefAutoPtr | |
// | |
// Written by "Daniel Ranger" <[email protected]> | |
// Copyright (c) 2009 Daniel Ranger | |
// | |
// DESCRIPTION | |
// | |
// CRefAutoPtr is a smart pointer class to manage reference count within | |
// a CRefObject class. A normal smart pointer class manages reference | |
// count within its own class however in this implementation you must | |
// "extend" an existing object with CRefObject so it can be used by a | |
// CRefAutoPtr. Here is an example of its use: | |
// | |
// class TExisting | |
// { | |
// ... | |
// }; | |
// | |
// VOID SomeFunc(LPVOID pvParam) | |
// { | |
// CRefAutoPtr<TExisting> sp((CRefObject<TExisting>*)pvParam); | |
// ... | |
// } | |
// | |
// CRefObject<TExisting>* p = | |
// CRefObject<TExisting>::CreateInstance(/* TExisting ctor args */); | |
// CRefAutoPtr<TExisting> sp(p); | |
// SomeFunc(&sp); // or SomeFunc(sp); both are the same | |
// | |
// LICENSE | |
// | |
// This is free software: you can redistribute it and/or modify | |
// it under the terms of the GNU General Public License as published by | |
// the Free Software Foundation, at version 3 of the License. | |
// | |
// This program is distributed in the hope that it will be useful, | |
// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
// GNU General Public License for more details. | |
// | |
// You should have received a copy of the GNU General Public License | |
// along with this program. If not, see <http://www.gnu.org/licenses/>. | |
// | |
///////////////////////////////////////////////////////////////////////////// | |
#ifndef __REFOBJ_H__ | |
#define __REFOBJ_H__ | |
#pragma once | |
#ifndef ATLASSERT | |
#define ATLASSERT(expr) _ASSERTE(expr) | |
#endif // ATLASSERT | |
template<typename T> | |
class CRefAutoPtr; | |
template<typename TBase, typename TActivator> | |
class CRefObject; | |
// CRefActivatorTraits | |
///////////////////////////////////////////////////////////////////////////// | |
template<typename TBase> | |
class CRefActivatorTraits | |
{ | |
typedef CRefObject<TBase, CRefActivatorTraits> T; | |
public: | |
static T* Create() | |
{ return new T(); } | |
template<typename T1> | |
static T* Create(T1 p1) | |
{ return new T(p1); } | |
template<typename T1, typename T2> | |
static T* Create(T1 p1, T2 p2) | |
{ return new T(p1, p2); } | |
template<typename T1, typename T2, typename T3> | |
static T* Create(T1 p1, T2 p2, T3 p3) | |
{ return new T(p1, p2, p3); } | |
template<typename T1, typename T2, typename T3, typename T4> | |
static T* Create(T1 p1, T2 p2, T3 p3, T4 p4) | |
{ return new T(p1, p2, p3, p4); } | |
template<typename T1, typename T2, typename T3, typename T4, typename T5> | |
static T* Create(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) | |
{ return new T(p1, p2, p3, p4, p5); } | |
static VOID Destroy(T* p) | |
{ delete p; } | |
}; | |
// CRefObject | |
///////////////////////////////////////////////////////////////////////////// | |
template<typename TBase, typename TActivator = CRefActivatorTraits<TBase>> | |
class CRefObject : public TBase | |
{ | |
friend TActivator; | |
template<typename T> | |
friend class CRefAutoPtr; | |
private: | |
CRefObject() | |
{ | |
_Init(); | |
} | |
explicit CRefObject(const CRefObject& o) | |
{ | |
_Init(o.m_lRefCount); | |
} | |
template<typename T1> | |
CRefObject(T1 p1) : | |
TBase(p1) | |
{ | |
_Init(); | |
} | |
template<typename T1, typename T2> | |
CRefObject(T1 p1, T2 p2) : | |
TBase(p1, p2) | |
{ | |
_Init(); | |
} | |
template<typename T1, typename T2, typename T3> | |
CRefObject(T1 p1, T2 p2, T3 p3) : | |
TBase(p1, p2, p3) | |
{ | |
_Init(); | |
} | |
template<typename T1, typename T2, typename T3, typename T4> | |
CRefObject(T1 p1, T2 p2, T3 p3, T4 p4) : | |
TBase(p1, p2, p3, p4) | |
{ | |
_Init(); | |
} | |
template<typename T1, typename T2, typename T3, typename T4, typename T5> | |
CRefObject(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) : | |
TBase(p1, p2, p3, p4, p5) | |
{ | |
_Init(); | |
} | |
public: | |
static CRefObject* CreateInstance() | |
{ | |
return TActivator::Create(); | |
} | |
template<typename T1> | |
static CRefObject* CreateInstance(T1 p1) | |
{ | |
return TActivator::Create(p1); | |
} | |
template<typename T1, typename T2> | |
static CRefObject* CreateInstance(T1 p1, T2 p2) | |
{ | |
return TActivator::Create(p1, p2); | |
} | |
template<typename T1, typename T2, typename T3> | |
static CRefObject* CreateInstance(T1 p1, T2 p2, T3 p3) | |
{ | |
return TActivator::Create(p1, p2, p3); | |
} | |
template<typename T1, typename T2, typename T3, typename T4> | |
static CRefObject* CreateInstance(T1 p1, T2 p2, T3 p3, T4 p4) | |
{ | |
return TActivator::Create(p1, p2, p3, p4); | |
} | |
template<typename T1, typename T2, typename T3, typename T4, typename T5> | |
static CRefObject* CreateInstance(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) | |
{ | |
return TActivator::Create(p1, p2, p3, p4, p5); | |
} | |
ULONG AddRef() | |
{ | |
return ::InterlockedIncrement(&m_lRefCount); | |
} | |
ULONG Release() | |
{ | |
LONG lCount = ::InterlockedDecrement(&m_lRefCount); | |
ATLASSERT(lCount >= 0); | |
if (lCount == 0) | |
TActivator::Destroy(this); | |
return lCount; | |
} | |
private: | |
VOID _Init(LONG lRefCount = 1) | |
{ | |
m_lRefCount = lRefCount; | |
} | |
VOID _Swap(CRefObject& o) | |
{ | |
_Swap(m_lRefCount, o.m_lRefCount); | |
} | |
template<typename T1, typename T2> | |
VOID _Swap(T1& p1, T2& p2) | |
{ | |
T1 tmp = p1; | |
p1 = p2; | |
p2 = tmp; | |
} | |
public: | |
LONG m_lRefCount; | |
}; | |
// CRefAutoPtr | |
///////////////////////////////////////////////////////////////////////////// | |
template<typename T> | |
class CRefAutoPtr | |
{ | |
public: | |
CRefAutoPtr() throw() : | |
m_pT(NULL) | |
{ } | |
CRefAutoPtr(const CRefAutoPtr& sp) throw() : | |
m_pT(sp.m_pT) | |
{ | |
_AddRef(); | |
} | |
explicit CRefAutoPtr(CRefObject<T>* pT) throw() : | |
m_pT(NULL) | |
{ | |
_Attach(pT); | |
} | |
virtual ~CRefAutoPtr() throw() | |
{ | |
_Release(); | |
} | |
CRefAutoPtr& operator =(const CRefAutoPtr& sp) throw() | |
{ | |
_Release(); | |
m_pT = sp.m_pT; | |
_AddRef(); | |
return *this; | |
} | |
CRefObject<T>* operator &() throw() | |
{ | |
_AddRef(); | |
return m_pT; | |
} | |
operator CRefObject<T>*() throw() | |
{ | |
return operator&(); | |
} | |
CRefObject<T>* operator ->() const throw() | |
{ | |
return m_pT; | |
} | |
bool operator !=(const CRefAutoPtr& sp) const throw() | |
{ | |
return !operator==(sp); | |
} | |
bool operator ==(const CRefAutoPtr& sp) const throw() | |
{ | |
return m_pT == sp.m_pT; | |
} | |
CRefObject<T>* Detach() throw() | |
{ | |
CRefObject<T>* pT = m_pT; | |
m_pT = NULL; | |
return pT; | |
} | |
protected: | |
VOID _Attach(CRefObject<T>* pT) throw() | |
{ | |
_Release(); | |
m_pT = pT; | |
} | |
VOID _AddRef() throw() | |
{ | |
CRefObject<T>* pT = m_pT; | |
if (pT) | |
pT->AddRef(); | |
} | |
VOID _Release() throw() | |
{ | |
CRefObject<T>* pT = m_pT; | |
if (pT) | |
{ | |
m_pT = NULL; | |
pT->Release(); | |
} | |
} | |
public: | |
CRefObject<T>* m_pT; | |
}; | |
#endif // __REFOBJ_H__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment