📄 smartptr.h
字号:
////////////////////////////////////////////////////////////////////////////////// The Loki Library// Copyright (c) 2001 by Andrei Alexandrescu// This code accompanies the book:// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design// Patterns Applied". Copyright (c) 2001. Addison-Wesley.// Permission to use, copy, modify, distribute and sell this software for any// purpose is hereby granted without fee, provided that the above copyright// notice appear in all copies and that both that copyright notice and this// permission notice appear in supporting documentation.// The author or Addison-Wesley Longman make no representations about the// suitability of this software for any purpose. It is provided "as is"// without express or implied warranty.////////////////////////////////////////////////////////////////////////////////#ifndef LOKI_SMARTPTR_INC_#define LOKI_SMARTPTR_INC_// $Id: SmartPtr.h 903 2008-11-10 05:55:12Z rich_sposato $/// \defgroup SmartPointerGroup Smart pointers/// Policy based implementation of a smart pointer/// \defgroup SmartPointerOwnershipGroup Ownership policies/// \ingroup SmartPointerGroup/// \defgroup SmartPointerStorageGroup Storage policies/// \ingroup SmartPointerGroup/// \defgroup SmartPointerConversionGroup Conversion policies/// \ingroup SmartPointerGroup/// \defgroup SmartPointerCheckingGroup Checking policies/// \ingroup SmartPointerGroup#include "LokiExport.h"#include "SmallObj.h"#include "TypeManip.h"#include "static_check.h"#include "RefToValue.h"#include "ConstPolicy.h"#include <functional>#include <stdexcept>#include <cassert>#include <string>#if !defined(_MSC_VER)# if defined(__sparc__)# include <inttypes.h># else# include <stdint.h># endif#endif#if defined(_MSC_VER) || defined(__GNUC__)// GCC>=4.1 must use -ffriend-injection due to a bug in GCC#define LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND#endifnamespace Loki{/////////////////////////////////////////////////////////////////////////////////// \class HeapStorage////// \ingroup SmartPointerStorageGroup/// Implementation of the StoragePolicy used by SmartPtr. Uses explicit call/// to T's destructor followed by call to free.//////////////////////////////////////////////////////////////////////////////// template <class T> class HeapStorage { 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* HeapStorage() : pointee_(Default()) {} // The storage policy doesn't initialize the stored pointer // which will be initialized by the OwnershipPolicy's Clone fn HeapStorage(const HeapStorage&) : pointee_(0) {} template <class U> HeapStorage(const HeapStorage<U>&) : pointee_(0) {} HeapStorage(const StoredType& p) : pointee_(p) {} PointerType operator->() const { return pointee_; } ReferenceType operator*() const { return *pointee_; } void Swap(HeapStorage& rhs) { std::swap(pointee_, rhs.pointee_); } // Accessors template <class F> friend typename HeapStorage<F>::PointerType GetImpl(const HeapStorage<F>& sp); template <class F> friend const typename HeapStorage<F>::StoredType& GetImplRef(const HeapStorage<F>& sp); template <class F> friend typename HeapStorage<F>::StoredType& GetImplRef(HeapStorage<F>& sp); protected: // Destroys the data stored // (Destruction might be taken over by the OwnershipPolicy) void Destroy() { if ( 0 != pointee_ ) { pointee_->~T(); ::free( pointee_ ); } } // Default value to initialize the pointer static StoredType Default() { return 0; } private: // Data StoredType pointee_; }; template <class T> inline typename HeapStorage<T>::PointerType GetImpl(const HeapStorage<T>& sp) { return sp.pointee_; } template <class T> inline const typename HeapStorage<T>::StoredType& GetImplRef(const HeapStorage<T>& sp) { return sp.pointee_; } template <class T> inline typename HeapStorage<T>::StoredType& GetImplRef(HeapStorage<T>& sp) { return sp.pointee_; }/////////////////////////////////////////////////////////////////////////////////// \class DefaultSPStorage////// \ingroup SmartPointerStorageGroup/// Implementation of the StoragePolicy used by SmartPtr//////////////////////////////////////////////////////////////////////////////// template <class T> class DefaultSPStorage { 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* DefaultSPStorage() : pointee_(Default()) {} // The storage policy doesn't initialize the stored pointer // which will be initialized by the OwnershipPolicy's Clone fn DefaultSPStorage(const DefaultSPStorage&) : pointee_(0) {} template <class U> DefaultSPStorage(const DefaultSPStorage<U>&) : pointee_(0) {} DefaultSPStorage(const StoredType& p) : pointee_(p) {} PointerType operator->() const { return pointee_; } ReferenceType operator*() const { return *pointee_; } void Swap(DefaultSPStorage& rhs) { std::swap(pointee_, rhs.pointee_); } // Accessors template <class F> friend typename DefaultSPStorage<F>::PointerType GetImpl(const DefaultSPStorage<F>& sp); template <class F> friend const typename DefaultSPStorage<F>::StoredType& GetImplRef(const DefaultSPStorage<F>& sp); template <class F> friend typename DefaultSPStorage<F>::StoredType& GetImplRef(DefaultSPStorage<F>& sp); protected: // Destroys the data stored // (Destruction might be taken over by the OwnershipPolicy) // // If your compiler gives you a warning in this area while // compiling the tests, it is on purpose, please ignore it. void Destroy() { delete pointee_; } // Default value to initialize the pointer static StoredType Default() { return 0; } private: // Data StoredType pointee_; }; template <class T> inline typename DefaultSPStorage<T>::PointerType GetImpl(const DefaultSPStorage<T>& sp) { return sp.pointee_; } template <class T> inline const typename DefaultSPStorage<T>::StoredType& GetImplRef(const DefaultSPStorage<T>& sp) { return sp.pointee_; } template <class T> inline typename DefaultSPStorage<T>::StoredType& GetImplRef(DefaultSPStorage<T>& sp) { return sp.pointee_; }/////////////////////////////////////////////////////////////////////////////////// \class LockedStorage////// \ingroup SmartPointerStorageGroup/// Implementation of the StoragePolicy used by SmartPtr.////// Each call to operator-> locks the object for the duration of a call to a/// member function of T.////// \par How It Works/// LockedStorage has a helper class called Locker, which acts as a smart/// pointer with limited abilities. LockedStorage::operator-> returns an/// unnamed temporary of type Locker<T> that exists for the duration of the/// call to a member function of T. The unnamed temporary locks the object/// when it is constructed by operator-> and unlocks the object when it is/// destructed.////// \note This storage policy requires class T to have member functions Lock/// and Unlock. If your class does not have Lock or Unlock functions, you may/// either make a child class which does, or make a policy class similar to/// LockedStorage which calls other functions to lock the object.//////////////////////////////////////////////////////////////////////////////// template <class T> 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 T> 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 <class F> friend typename LockedStorage<F>::InitPointerType GetImpl(const LockedStorage<F>& sp); template <class F> friend const typename LockedStorage<F>::StoredType& GetImplRef(const LockedStorage<F>& sp); template <class F> friend typename LockedStorage<F>::StoredType& GetImplRef(LockedStorage<F>& 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 <class T> inline typename LockedStorage<T>::InitPointerType GetImpl(const LockedStorage<T>& sp) { return sp.pointee_; } template <class T> inline const typename LockedStorage<T>::StoredType& GetImplRef(const LockedStorage<T>& sp) { return sp.pointee_; } template <class T> inline typename LockedStorage<T>::StoredType& GetImplRef(LockedStorage<T>& sp) { return sp.pointee_; }/////////////////////////////////////////////////////////////////////////////////// \class ArrayStorage////// \ingroup SmartPointerStorageGroup/// Implementation of the ArrayStorage used by SmartPtr//////////////////////////////////////////////////////////////////////////////// template <class T> class ArrayStorage { 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* ArrayStorage() : pointee_(Default()) {} // The storage policy doesn't initialize the stored pointer // which will be initialized by the OwnershipPolicy's Clone fn ArrayStorage(const ArrayStorage&) : pointee_(0) {} template <class U> ArrayStorage(const ArrayStorage<U>&) : pointee_(0) {} ArrayStorage(const StoredType& p) : pointee_(p) {} PointerType operator->() const { return pointee_; } ReferenceType operator*() const { return *pointee_; } void Swap(ArrayStorage& rhs) { std::swap(pointee_, rhs.pointee_); } // Accessors template <class F> friend typename ArrayStorage<F>::PointerType GetImpl(const ArrayStorage<F>& sp); template <class F> friend const typename ArrayStorage<F>::StoredType& GetImplRef(const ArrayStorage<F>& sp); template <class F> friend typename ArrayStorage<F>::StoredType& GetImplRef(ArrayStorage<F>& 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: // Data StoredType pointee_; }; template <class T> inline typename ArrayStorage<T>::PointerType GetImpl(const ArrayStorage<T>& sp) { return sp.pointee_; } template <class T> inline const typename ArrayStorage<T>::StoredType& GetImplRef(const ArrayStorage<T>& sp) { return sp.pointee_; } template <class T> inline typename ArrayStorage<T>::StoredType& GetImplRef(ArrayStorage<T>& sp) { return sp.pointee_; }/////////////////////////////////////////////////////////////////////////////////// \class RefCounted////// \ingroup SmartPointerOwnershipGroup/// Implementation of the OwnershipPolicy used by SmartPtr/// Provides a classic external reference counting implementation//////////////////////////////////////////////////////////////////////////////// template <class P> class RefCounted { public: RefCounted() : pCount_(static_cast<uintptr_t*>( SmallObject<>::operator new(sizeof(uintptr_t)))) { assert(pCount_!=0); *pCount_ = 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -