smartptr.h
来自「C++封装的视频采集代码」· C头文件 代码 · 共 1,203 行 · 第 1/3 页
H
1,203 行
////////////////////////////////////////////////////////////////////////////////// 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.////////////////////////////////////////////////////////////////////////////////// Last update: August 9, 2002#ifndef SMARTPTR_INC_#define SMARTPTR_INC_////////////////////////////////////////////////////////////////////////////////// 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////////////////////////////////////////////////////////////////////////////////#include "SmallObj.h"#include "TypeManip.h"#include "static_check.h"#include <functional>#include <stdexcept>#include "Utils/assert.h"#include "Utils/excdef.h"#include "SysLib/xdbg.h"namespace Loki{////////////////////////////////////////////////////////////////////////////////// class template DefaultSPStorage// Implementation of the StoragePolicy used by SmartPtr//////////////////////////////////////////////////////////////////////////////// template <class T> class DefaultSPStorage { public: typedef T* StoredType; // the type of the pointee_ object typedef T* PointerType; // type returned by operator-> typedef T& ReferenceType; // type returned by operator* public: 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&) {} template <class U> DefaultSPStorage(const DefaultSPStorage<U>&) {} 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 friend inline PointerType GetImpl(const DefaultSPStorage& sp) { return sp.pointee_; } friend inline const StoredType& GetImplRef(const DefaultSPStorage& sp) { return sp.pointee_; } friend inline StoredType& GetImplRef(DefaultSPStorage& sp) { return sp.pointee_; } 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_; };////////////////////////////////////////////////////////////////////////////////// class template RefCounted// Implementation of the OwnershipPolicy used by SmartPtr// Provides a classic external reference counting implementation//////////////////////////////////////////////////////////////////////////////// template <class P> class RefCounted { public: RefCounted() { pCount_ = static_cast<unsigned int*>( SmallObject<>::operator new(sizeof(unsigned int))); ASSERT(pCount_); *pCount_ = 1; } 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(unsigned int)); return true; } return false; } void Swap(RefCounted& rhs) { std::swap(pCount_, rhs.pCount_); } enum { destructiveCopy = false }; private: // Data unsigned int* pCount_; };////////////////////////////////////////////////////////////////////////////////// class template RefCountedMT// Implementation of the OwnershipPolicy used by SmartPtr// Implements external reference counting for multithreaded programs//////////////////////////////////////////////////////////////////////////////// template <class P, template <class> class ThreadingModel> class RefCountedMT : public ThreadingModel< RefCountedMT<P, ThreadingModel> > { public: RefCountedMT() { pCount_ = static_cast<unsigned int*>( SmallObject<ThreadingModel>::operator new( sizeof(unsigned int))); ASSERT(pCount_); *pCount_ = 1; } RefCountedMT(const RefCountedMT& rhs) : pCount_(rhs.pCount_) {} // MWCW lacks template friends, hence the following kludge template <typename P1> RefCountedMT(const RefCountedMT<P1, ThreadingModel>& rhs) : pCount_(reinterpret_cast<const RefCounted<P>&>(rhs).pCount_) {} P Clone(const P& val) { ThreadingModel<RefCountedMT>::AtomicIncrement(*pCount_); return val; } bool Release(const P&) { if (!ThreadingModel<RefCountedMT>::AtomicDecrement(*pCount_)) { SmallObject<ThreadingModel>::operator delete(pCount_, sizeof(unsigned int)); return true; } return false; } void Swap(RefCountedMT& rhs) { std::swap(pCount_, rhs.pCount_); } enum { destructiveCopy = false }; private: // Data volatile unsigned int* pCount_; };////////////////////////////////////////////////////////////////////////////////// class template COMRefCounted// 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) { val->AddRef(); return val; } static bool Release(const P& val) { val->Release(); return false; } enum { destructiveCopy = false }; static void Swap(COMRefCounted&) {} };////////////////////////////////////////////////////////////////////////////////// class template DeepCopy// 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& val) { return true; } static void Swap(DeepCopy&) {} enum { destructiveCopy = false }; };////////////////////////////////////////////////////////////////////////////////// class template RefLinked// Implementation of the OwnershipPolicy used by SmartPtr// Implements reference linking//////////////////////////////////////////////////////////////////////////////// namespace Private { class RefLinkedBase { public: RefLinkedBase() { prev_ = next_ = this; } RefLinkedBase(const RefLinkedBase& rhs) { prev_ = &rhs; next_ = rhs.next_; prev_->next_ = this; next_->prev_ = this; } bool Release() { if (next_ == this) { ASSERT(prev_ == this); return true; } prev_->next_ = next_; next_->prev_ = prev_; return false; } void Swap(RefLinkedBase& rhs) { if (next_ == this) { ASSERT(prev_ == this); if (rhs.next_ == &rhs) { ASSERT(rhs.prev_ == &rhs); // both lists are empty, nothing 2 do return; } prev_ = rhs.prev_; next_ = rhs.next_; prev_->next_ = next_->prev_ = this; rhs.next_ = rhs.prev_ = &rhs; return; } if (rhs.next_ == &rhs) { rhs.Swap(*this); return; } std::swap(prev_, rhs.prev_); std::swap(next_, rhs.next_); std::swap(prev_->next_, rhs.prev_->next_); std::swap(next_->prev_, rhs.next_->prev_); } enum { destructiveCopy = false }; private: 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(); } }; ////////////////////////////////////////////////////////////////////////////////// class template DestructiveCopy// 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 template NoCopy// Implementation of the OwnershipPolicy used by SmartPtr// Implements a policy that doesn't allow copying objects////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?