📄 smartptr.h
字号:
template <class U> AssertCheckStrict(const AssertCheckStrict<U>&) {} template <class U> AssertCheckStrict(const AssertCheck<U>&) {} template <class P1> AssertCheckStrict(const NoCheck<P1>&) {} static void OnDefault(P val) { assert(val); } static void OnInit(P val) { assert(val); } static void OnDereference(P val) { assert(val); } static void Swap(AssertCheckStrict&) {} };/////////////////////////////////////////////////////////////////////////////////// \struct NullPointerException////// \ingroup SmartPointerGroup/// Used by some implementations of the CheckingPolicy used by SmartPtr//////////////////////////////////////////////////////////////////////////////// struct NullPointerException : public std::runtime_error { NullPointerException() : std::runtime_error(std::string("")) { } const char* what() const throw() { return "Null Pointer Exception"; } };/////////////////////////////////////////////////////////////////////////////////// \struct RejectNullStatic////// \ingroup SmartPointerCheckingGroup/// Implementation of the CheckingPolicy used by SmartPtr/// Checks the pointer upon initialization and before dereference//////////////////////////////////////////////////////////////////////////////// template <class P> struct RejectNullStatic { RejectNullStatic() {} template <class P1> RejectNullStatic(const RejectNullStatic<P1>&) {} template <class P1> RejectNullStatic(const NoCheck<P1>&) {} template <class P1> RejectNullStatic(const AssertCheck<P1>&) {} template <class P1> RejectNullStatic(const AssertCheckStrict<P1>&) {} static void OnDefault(const P&) { // Make it depended on template parameter static const bool DependedFalse = sizeof(P*) == 0; LOKI_STATIC_CHECK(DependedFalse, ERROR_This_Policy_Does_Not_Allow_Default_Initialization); } static void OnInit(const P& val) { if (!val) throw NullPointerException(); } static void OnDereference(const P& val) { if (!val) throw NullPointerException(); } static void Swap(RejectNullStatic&) {} };/////////////////////////////////////////////////////////////////////////////////// \struct RejectNull////// \ingroup SmartPointerCheckingGroup/// Implementation of the CheckingPolicy used by SmartPtr/// Checks the pointer before dereference//////////////////////////////////////////////////////////////////////////////// template <class P> struct RejectNull { RejectNull() {} template <class P1> RejectNull(const RejectNull<P1>&) {} static void OnInit(P) {} static void OnDefault(P) {} void OnDereference(P val) { if (!val) throw NullPointerException(); } void OnDereference(P val) const { if (!val) throw NullPointerException(); } void Swap(RejectNull&) {} };/////////////////////////////////////////////////////////////////////////////////// \struct RejectNullStrict////// \ingroup SmartPointerCheckingGroup/// Implementation of the CheckingPolicy used by SmartPtr/// Checks the pointer upon initialization and before dereference//////////////////////////////////////////////////////////////////////////////// template <class P> struct RejectNullStrict { RejectNullStrict() {} template <class P1> RejectNullStrict(const RejectNullStrict<P1>&) {} template <class P1> RejectNullStrict(const RejectNull<P1>&) {} static void OnInit(P val) { if (!val) throw NullPointerException(); } void OnDereference(P val) { OnInit(val); } void OnDereference(P val) const { OnInit(val); } void Swap(RejectNullStrict&) {} };////////////////////////////////////////////////////////////////////////////////// class template SmartPtr (declaration)// The reason for all the fuss above//////////////////////////////////////////////////////////////////////////////// template < typename T, template <class> class OwnershipPolicy = RefCounted, class ConversionPolicy = DisallowConversion, template <class> class CheckingPolicy = AssertCheck, template <class> class StoragePolicy = DefaultSPStorage, template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS > class SmartPtr;////////////////////////////////////////////////////////////////////////////////// class template SmartPtrDef (definition)// this class added to unify the usage of SmartPtr// instead of writing SmartPtr<T,OP,CP,KP,SP> write SmartPtrDef<T,OP,CP,KP,SP>::type//////////////////////////////////////////////////////////////////////////////// template < typename T, template <class> class OwnershipPolicy = RefCounted, class ConversionPolicy = DisallowConversion, template <class> class CheckingPolicy = AssertCheck, template <class> class StoragePolicy = DefaultSPStorage, template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS > struct SmartPtrDef { typedef SmartPtr < T, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy, ConstnessPolicy > type; };/////////////////////////////////////////////////////////////////////////////////// \class SmartPtr////// \ingroup SmartPointerGroup////// \param OwnershipPolicy default = RefCounted,/// \param ConversionPolicy default = DisallowConversion,/// \param CheckingPolicy default = AssertCheck,/// \param StoragePolicy default = DefaultSPStorage/// \param ConstnessPolicy default = LOKI_DEFAULT_CONSTNESS////// \par IMPORTANT NOTE/// Due to threading issues, the OwnershipPolicy has been changed as follows:////// - Release() returns a boolean saying if that was the last release/// so the pointer can be deleted by the StoragePolicy/// - IsUnique() was removed//////////////////////////////////////////////////////////////////////////////// template < typename T, template <class> class OwnershipPolicy, class ConversionPolicy, template <class> class CheckingPolicy, template <class> class StoragePolicy, template <class> class ConstnessPolicy > class SmartPtr : public StoragePolicy<T> , public OwnershipPolicy<typename StoragePolicy<T>::InitPointerType> , public CheckingPolicy<typename StoragePolicy<T>::StoredType> , public ConversionPolicy { typedef StoragePolicy<T> SP; typedef OwnershipPolicy<typename StoragePolicy<T>::InitPointerType> OP; typedef CheckingPolicy<typename StoragePolicy<T>::StoredType> KP; typedef ConversionPolicy CP; public: typedef typename ConstnessPolicy<T>::Type* ConstPointerType; typedef typename ConstnessPolicy<T>::Type& ConstReferenceType; typedef typename SP::PointerType PointerType; typedef typename SP::StoredType StoredType; typedef typename SP::ReferenceType ReferenceType; typedef typename Select<OP::destructiveCopy,SmartPtr, const SmartPtr>::Result CopyArg; private: struct NeverMatched {};#ifdef LOKI_SMARTPTR_CONVERSION_CONSTRUCTOR_POLICY typedef typename Select< CP::allow, const StoredType&, NeverMatched>::Result ImplicitArg; typedef typename Select<!CP::allow, const StoredType&, NeverMatched>::Result ExplicitArg;#else typedef const StoredType& ImplicitArg; typedef typename Select<false, const StoredType&, NeverMatched>::Result ExplicitArg;#endif public: SmartPtr() { KP::OnDefault(GetImpl(*this)); } explicit SmartPtr(ExplicitArg p) : SP(p) { KP::OnInit(GetImpl(*this)); } SmartPtr(ImplicitArg p) : SP(p) { KP::OnInit(GetImpl(*this)); } SmartPtr(CopyArg& rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs) { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } template < typename T1, template <class> class OP1, class CP1, template <class> class KP1, template <class> class SP1, template <class> class CNP1 > SmartPtr(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs) { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } template < typename T1, template <class> class OP1, class CP1, template <class> class KP1, template <class> class SP1, template <class> class CNP1 > SmartPtr(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs) { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } SmartPtr(RefToValue<SmartPtr> rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs) {} operator RefToValue<SmartPtr>() { return RefToValue<SmartPtr>(*this); } SmartPtr& operator=(CopyArg& rhs) { SmartPtr temp(rhs); temp.Swap(*this); return *this; } template < typename T1, template <class> class OP1, class CP1, template <class> class KP1, template <class> class SP1, template <class> class CNP1 > SmartPtr& operator=(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) { SmartPtr temp(rhs); temp.Swap(*this); return *this; } template < typename T1, template <class> class OP1, class CP1, template <class> class KP1, template <class> class SP1, template <class> class CNP1 > SmartPtr& operator=(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) { SmartPtr temp(rhs); temp.Swap(*this); return *this; } void Swap(SmartPtr& rhs) { OP::Swap(rhs); CP::Swap(rhs); KP::Swap(rhs); SP::Swap(rhs); } ~SmartPtr() { if (OP::Release(GetImpl(*static_cast<SP*>(this)))) { SP::Destroy(); } }#ifdef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND // old non standard in class definition of friends friend inline void Release(SmartPtr& sp, typename SP::StoredType& p) { p = GetImplRef(sp); GetImplRef(sp) = SP::Default(); } friend inline void Reset(SmartPtr& sp, typename SP::StoredType p) { SmartPtr(p).Swap(sp); }#else template < typename T1, template <class> class OP1, class CP1, template <class> class KP1, template <class> class SP1, template <class> class CNP1 > friend void Release(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1>& sp, typename SP1<T1>::StoredType& p); template < typename T1, template <class> class OP1, class CP1, template <class> class KP1, template <class> class SP1, template <class> class CNP1 > friend void Reset(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1>& sp, typename SP1<T1>::StoredType p);#endif template < typename T1, template <class> class OP1, class CP1, template <class> class KP1, template <class> class SP1, template <class> class CNP1 > bool Merge( SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs ) { if ( GetImpl( *this ) != GetImpl( rhs ) ) { return false; } return OP::template Merge( rhs ); } PointerType operator->() { KP::OnDereference(GetImplRef(*this)); return SP::operator->(); } ConstPointerType operator->() const { KP::OnDereference(GetImplRef(*this)); return SP::operator->();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -