📄 smartptr.h
字号:
RefCounted(const RefCounted& rhs) : pCount_(rhs.pCount_) {} // MWCW lacks template friends, hence the following kludge template <typename P1> RefCounted(const RefCounted<P1>& rhs) : pCount_(reinterpret_cast<const RefCounted&>(rhs).pCount_) {} P Clone(const P& val) { ++*pCount_; return val; } bool Release(const P&) { if (!--*pCount_) { SmallObject<>::operator delete(pCount_, sizeof(uintptr_t)); pCount_ = NULL; return true; } return false; } void Swap(RefCounted& rhs) { std::swap(pCount_, rhs.pCount_); } enum { destructiveCopy = false }; private: // Data uintptr_t* pCount_; };/////////////////////////////////////////////////////////////////////////////////// \struct RefCountedMT////// \ingroup SmartPointerOwnershipGroup/// Implementation of the OwnershipPolicy used by SmartPtr/// Implements external reference counting for multithreaded programs/// Policy Usage: RefCountedMTAdj<ThreadingModel>::RefCountedMT////// \par Warning/// There could be a race condition, see bug "Race condition in RefCountedMTAdj::Release"/// http://sourceforge.net/tracker/index.php?func=detail&aid=1408845&group_id=29557&atid=396644/// As stated in bug 1408845, the Release function is not thread safe if a/// SmartPtr copy-constructor tries to copy the last pointer to an object in/// one thread, while the destructor is acting on the last pointer in another/// thread. The existence of a race between a copy-constructor and destructor/// implies a design flaw at a higher level. That race condition must be/// fixed at a higher design level, and no change to this class could fix it.//////////////////////////////////////////////////////////////////////////////// template <template <class, class> class ThreadingModel, class MX = LOKI_DEFAULT_MUTEX > struct RefCountedMTAdj { template <class P> class RefCountedMT : public ThreadingModel< RefCountedMT<P>, MX > { typedef ThreadingModel< RefCountedMT<P>, MX > base_type; typedef typename base_type::IntType CountType; typedef volatile CountType *CountPtrType; public: RefCountedMT() { pCount_ = static_cast<CountPtrType>( SmallObject<LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>::operator new( sizeof(*pCount_))); assert(pCount_); //*pCount_ = 1; ThreadingModel<RefCountedMT, MX>::AtomicAssign(*pCount_, 1); } RefCountedMT(const RefCountedMT& rhs) : pCount_(rhs.pCount_) {} //MWCW lacks template friends, hence the following kludge template <typename P1> RefCountedMT(const RefCountedMT<P1>& rhs) : pCount_(reinterpret_cast<const RefCountedMT<P>&>(rhs).pCount_) {} P Clone(const P& val) { ThreadingModel<RefCountedMT, MX>::AtomicIncrement(*pCount_); return val; } bool Release(const P&) { bool isZero = false; ThreadingModel< RefCountedMT, MX >::AtomicDecrement( *pCount_, 0, isZero ); if ( isZero ) { SmallObject<LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>::operator delete( const_cast<CountType *>(pCount_), sizeof(*pCount_)); return true; } return false; } void Swap(RefCountedMT& rhs) { std::swap(pCount_, rhs.pCount_); } enum { destructiveCopy = false }; private: // Data CountPtrType pCount_; }; };/////////////////////////////////////////////////////////////////////////////////// \class COMRefCounted////// \ingroup SmartPointerOwnershipGroup/// Implementation of the OwnershipPolicy used by SmartPtr/// Adapts COM intrusive reference counting to OwnershipPolicy-specific syntax//////////////////////////////////////////////////////////////////////////////// template <class P> class COMRefCounted { public: COMRefCounted() {} template <class U> COMRefCounted(const COMRefCounted<U>&) {} static P Clone(const P& val) { if(val!=0) val->AddRef(); return val; } static bool Release(const P& val) { if(val!=0) val->Release(); return false; } enum { destructiveCopy = false }; static void Swap(COMRefCounted&) {} };/////////////////////////////////////////////////////////////////////////////////// \struct DeepCopy////// \ingroup SmartPointerOwnershipGroup/// Implementation of the OwnershipPolicy used by SmartPtr/// Implements deep copy semantics, assumes existence of a Clone() member/// function of the pointee type//////////////////////////////////////////////////////////////////////////////// template <class P> struct DeepCopy { DeepCopy() {} template <class P1> DeepCopy(const DeepCopy<P1>&) {} static P Clone(const P& val) { return val->Clone(); } static bool Release(const P&) { return true; } static void Swap(DeepCopy&) {} enum { destructiveCopy = false }; };/////////////////////////////////////////////////////////////////////////////////// \class RefLinked////// \ingroup SmartPointerOwnershipGroup/// Implementation of the OwnershipPolicy used by SmartPtr/// Implements reference linking//////////////////////////////////////////////////////////////////////////////// namespace Private { class LOKI_EXPORT RefLinkedBase { public: RefLinkedBase() { prev_ = next_ = this; } RefLinkedBase(const RefLinkedBase& rhs); bool Release(); void Swap(RefLinkedBase& rhs); bool Merge( RefLinkedBase & rhs ); enum { destructiveCopy = false }; private: static unsigned int CountPrevCycle( const RefLinkedBase * pThis ); static unsigned int CountNextCycle( const RefLinkedBase * pThis ); bool HasPrevNode( const RefLinkedBase * p ) const; bool HasNextNode( const RefLinkedBase * p ) const; mutable const RefLinkedBase* prev_; mutable const RefLinkedBase* next_; }; } template <class P> class RefLinked : public Private::RefLinkedBase { public: RefLinked() {} template <class P1> RefLinked(const RefLinked<P1>& rhs) : Private::RefLinkedBase(rhs) {} static P Clone(const P& val) { return val; } bool Release(const P&) { return Private::RefLinkedBase::Release(); } template < class P1 > bool Merge( RefLinked< P1 > & rhs ) { return Private::RefLinkedBase::Merge( rhs ); } };/////////////////////////////////////////////////////////////////////////////////// \class DestructiveCopy////// \ingroup SmartPointerOwnershipGroup/// Implementation of the OwnershipPolicy used by SmartPtr/// Implements destructive copy semantics (a la std::auto_ptr)//////////////////////////////////////////////////////////////////////////////// template <class P> class DestructiveCopy { public: DestructiveCopy() {} template <class P1> DestructiveCopy(const DestructiveCopy<P1>&) {} template <class P1> static P Clone(P1& val) { P result(val); val = P1(); return result; } static bool Release(const P&) { return true; } static void Swap(DestructiveCopy&) {} enum { destructiveCopy = true }; };/////////////////////////////////////////////////////////////////////////////////// \class NoCopy////// \ingroup SmartPointerOwnershipGroup/// Implementation of the OwnershipPolicy used by SmartPtr/// Implements a policy that doesn't allow copying objects//////////////////////////////////////////////////////////////////////////////// template <class P> class NoCopy { public: NoCopy() {} template <class P1> NoCopy(const NoCopy<P1>&) {} static P Clone(const P&) { // Make it depended on template parameter static const bool DependedFalse = sizeof(P*) == 0; LOKI_STATIC_CHECK(DependedFalse, This_Policy_Disallows_Value_Copying); } static bool Release(const P&) { return true; } static void Swap(NoCopy&) {} enum { destructiveCopy = false }; };/////////////////////////////////////////////////////////////////////////////////// \struct AllowConversion////// \ingroup SmartPointerConversionGroup/// Implementation of the ConversionPolicy used by SmartPtr/// Allows implicit conversion from SmartPtr to the pointee type//////////////////////////////////////////////////////////////////////////////// struct AllowConversion { enum { allow = true }; void Swap(AllowConversion&) {} };/////////////////////////////////////////////////////////////////////////////////// \struct DisallowConversion////// \ingroup SmartPointerConversionGroup/// Implementation of the ConversionPolicy used by SmartPtr/// Does not allow implicit conversion from SmartPtr to the pointee type/// You can initialize a DisallowConversion with an AllowConversion//////////////////////////////////////////////////////////////////////////////// struct DisallowConversion { DisallowConversion() {} DisallowConversion(const AllowConversion&) {} enum { allow = false }; void Swap(DisallowConversion&) {} };/////////////////////////////////////////////////////////////////////////////////// \struct NoCheck////// \ingroup SmartPointerCheckingGroup/// Implementation of the CheckingPolicy used by SmartPtr/// Well, it's clear what it does :o)//////////////////////////////////////////////////////////////////////////////// template <class P> struct NoCheck { NoCheck() {} template <class P1> NoCheck(const NoCheck<P1>&) {} static void OnDefault(const P&) {} static void OnInit(const P&) {} static void OnDereference(const P&) {} static void Swap(NoCheck&) {} };/////////////////////////////////////////////////////////////////////////////////// \struct AssertCheck////// \ingroup SmartPointerCheckingGroup/// Implementation of the CheckingPolicy used by SmartPtr/// Checks the pointer before dereference//////////////////////////////////////////////////////////////////////////////// template <class P> struct AssertCheck { AssertCheck() {} template <class P1> AssertCheck(const AssertCheck<P1>&) {} template <class P1> AssertCheck(const NoCheck<P1>&) {} static void OnDefault(const P&) {} static void OnInit(const P&) {} static void OnDereference(P val) { assert(val); (void)val; } static void Swap(AssertCheck&) {} };/////////////////////////////////////////////////////////////////////////////////// \struct AssertCheckStrict////// \ingroup SmartPointerCheckingGroup/// Implementation of the CheckingPolicy used by SmartPtr/// Checks the pointer against zero upon initialization and before dereference/// You can initialize an AssertCheckStrict with an AssertCheck//////////////////////////////////////////////////////////////////////////////// template <class P> struct AssertCheckStrict { AssertCheckStrict() {}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -