From eb92853ac116e64b34e6edb23dea5e40deaa626a Mon Sep 17 00:00:00 2001 From: rich_sposato Date: Tue, 21 Nov 2006 01:34:45 +0000 Subject: [PATCH] Added LockedStorage policy for feature 1441024. git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@783 7ec92016-0320-0410-acc4-a06ded1c099a --- include/loki/SmartPtr.h | 149 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 136 insertions(+), 13 deletions(-) diff --git a/include/loki/SmartPtr.h b/include/loki/SmartPtr.h index eb6aba9..6efa1b7 100644 --- a/include/loki/SmartPtr.h +++ b/include/loki/SmartPtr.h @@ -67,9 +67,10 @@ namespace Loki class HeapStorage { public: - typedef T* StoredType; // the type of the pointee_ object - typedef T* PointerType; // type returned by operator-> - typedef T& ReferenceType; // type returned by operator* + typedef T* StoredType; /// the type of the pointee_ object + typedef T* InitPointerType; /// type used to declare OwnershipPolicy type. + typedef T* PointerType; /// type returned by operator-> + typedef T& ReferenceType; /// type returned by operator* HeapStorage() : pointee_(Default()) {} @@ -149,6 +150,7 @@ namespace Loki { public: typedef T* StoredType; // the type of the pointee_ object + typedef T* InitPointerType; /// type used to declare OwnershipPolicy type. typedef T* PointerType; // type returned by operator-> typedef T& ReferenceType; // type returned by operator* @@ -212,7 +214,118 @@ namespace Loki inline typename DefaultSPStorage::StoredType& GetImplRef(DefaultSPStorage& sp) { return sp.pointee_; } - + +//////////////////////////////////////////////////////////////////////////////// +/// \class LockedStorage +/// +/// \ingroup SmartPointerStorageGroup +/// Implementation of the StoragePolicy used by SmartPtr. +/// Requires class T to have member functions Lock and Unlock. +//////////////////////////////////////////////////////////////////////////////// + + template + class Locker + { + public: + Locker( const T * p ) : pointee_( const_cast< T * >( p ) ) + { + if ( pointee_ != 0 ) + pointee_->Lock(); + } + + ~Locker( void ) + { + if ( pointee_ != 0 ) + pointee_->Unlock(); + } + + operator T * () + { + return pointee_; + } + + T * operator->() + { + return pointee_; + } + + private: + Locker( void ); + Locker & operator = ( const Locker & ); + T * pointee_; + }; + + template + class LockedStorage + { + public: + + typedef T* StoredType; /// the type of the pointee_ object + typedef T* InitPointerType; /// type used to declare OwnershipPolicy type. + typedef Locker< T > PointerType; /// type returned by operator-> + typedef T& ReferenceType; /// type returned by operator* + + LockedStorage() : pointee_( Default() ) {} + + ~LockedStorage( void ) {} + + LockedStorage( const LockedStorage&) : pointee_( 0 ) {} + + LockedStorage( const StoredType & p ) : pointee_( p ) {} + + PointerType operator->() + { + return Locker< T >( pointee_ ); + } + + void Swap(LockedStorage& rhs) + { + std::swap( pointee_, rhs.pointee_ ); + } + + // Accessors + template + friend typename LockedStorage::InitPointerType GetImpl(const LockedStorage& sp); + + template + friend const typename LockedStorage::StoredType& GetImplRef(const LockedStorage& sp); + + template + friend typename LockedStorage::StoredType& GetImplRef(LockedStorage& sp); + + protected: + // Destroys the data stored + // (Destruction might be taken over by the OwnershipPolicy) + void Destroy() + { + delete pointee_; + } + + // Default value to initialize the pointer + static StoredType Default() + { return 0; } + + private: + /// Dereference operator is not implemented. + ReferenceType operator*(); + + // Data + StoredType pointee_; + }; + + template + inline typename LockedStorage::InitPointerType GetImpl(const LockedStorage& sp) + { return sp.pointee_; } + + template + inline const typename LockedStorage::StoredType& GetImplRef(const LockedStorage& sp) + { return sp.pointee_; } + + template + inline typename LockedStorage::StoredType& GetImplRef(LockedStorage& sp) + { return sp.pointee_; } + + //////////////////////////////////////////////////////////////////////////////// /// \class ArrayStorage /// @@ -226,6 +339,7 @@ namespace Loki { public: typedef T* StoredType; // the type of the pointee_ object + typedef T* InitPointerType; /// type used to declare OwnershipPolicy type. typedef T* PointerType; // type returned by operator-> typedef T& ReferenceType; // type returned by operator* @@ -977,12 +1091,12 @@ namespace Loki > class SmartPtr : public StoragePolicy - , public OwnershipPolicy::PointerType> + , public OwnershipPolicy::InitPointerType> , public CheckingPolicy::StoredType> , public ConversionPolicy { typedef StoragePolicy SP; - typedef OwnershipPolicy::PointerType> OP; + typedef OwnershipPolicy::InitPointerType> OP; typedef CheckingPolicy::StoredType> KP; typedef ConversionPolicy CP; @@ -1011,18 +1125,25 @@ namespace Loki public: SmartPtr() - { KP::OnDefault(GetImpl(*this)); } + { + KP::OnDefault(GetImpl(*this)); + } explicit SmartPtr(ExplicitArg p) : SP(p) - { KP::OnInit(GetImpl(*this)); } + { + KP::OnInit(GetImpl(*this)); + } SmartPtr(ImplicitArg p) : SP(p) - { KP::OnInit(GetImpl(*this)); } + { + KP::OnInit(GetImpl(*this)); + } - SmartPtr(CopyArg& rhs) - : SP(rhs), OP(rhs), KP(rhs), CP(rhs) - { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } + SmartPtr(CopyArg& rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs) + { + GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); + } template < @@ -1048,7 +1169,9 @@ namespace Loki > SmartPtr(SmartPtr& rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs) - { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } + { + GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); + } SmartPtr(RefToValue rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs)