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 + -
显示快捷键?