⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smartptr.h

📁 loki库的源代码。loki库是以模板技术和面向对象技术为基础的c++类库。
💻 H
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////////////////////////////////
// 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.
////////////////////////////////////////////////////////////////////////////////


// ported RefCountedMT
// To create a SmartPtr with RefCountedMT as ownership policy
// use code like this:
// SmartPtr<Foo, RefCountedMTWrapper<ClassLevelLockable> > pointer;
//
// replaced all template template parameters with 'normal' parameters
// For each Policy there is now a wrapper-class (non template class)
// containing a nested template class called In which
// provides a typedef (type) to the real Policy-class
//
// VC special: The MSVC 6.0 introduces an order-dependency for template ctor
// resp. template assignemt operators.
// If you need both a copy-ctor and a template copy ctor (same for copy-assignment), then
// you *must* write the templated version first.
// So instead of
//	template <class T>
//	struct Foo
//	{
//		Foo(const Foo&)
//		{}
//		template <class U>
//		Foo(const Foo<U>& r)
//		{}
//	};
// you *need* to write:
//	template <class T>
//	struct Foo
//	{
//		template <class U>
//		Foo(const Foo<U>& r)
//		{}
//
//		Foo(const Foo& r)
//		{}
//	};
//
// Many thanks to Nelson El骾 for pointing that out and for providing me
// with this solution


#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 "MSVC6Helpers.h"
#include "static_check.h"
#include "NullType.h"
#include <functional>
#include <stdexcept>
#include <cassert>

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

		// do not alter the order of the following two constructors
		// otherwise the MSVC 6.0 will not compile the class.
		template <class U>
		DefaultSPStorage(const DefaultSPStorage<U>&)  {}

		DefaultSPStorage(const DefaultSPStorage&)
        {}

		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_;
    };

	struct DefaultSPStorageWrapper
	{
		template <class T>
		struct In
		{
			typedef DefaultSPStorage<T> type;
		};
	};

////////////////////////////////////////////////////////////////////////////////
// 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;
        }

		// do not alter the order of the following two constructors
		// otherwise the MSVC 6.0 will fail to compile the class.

		// MWCW lacks template friends, hence the following kludge
        template <typename P1>
        RefCounted(const RefCounted<P1>& rhs)
        : pCount_(reinterpret_cast<const RefCounted&>(rhs).pCount_)
        {}

		RefCounted(const RefCounted& rhs)
        : pCount_(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_;
    };


	struct RefCountedWrapper
	{
		template<class T>
		struct In
		{
			typedef RefCounted<T> type;
		};
	};
////////////////////////////////////////////////////////////////////////////////
// class template RefCountedMT
// Implementation of the OwnershipPolicy used by SmartPtr
// Implements external reference counting for multithreaded programs
////////////////////////////////////////////////////////////////////////////////
//

	template <class P, class ThreadingModel>
	class RefCountedMT : public Apply1<ThreadingModel, RefCountedMT<P, ThreadingModel> >
    {
    public:
		typedef Apply1<ThreadingModel, RefCountedMT<P, ThreadingModel> > base_type;
		typedef typename base_type::IntType       CountType;
        typedef volatile CountType               *CountPtrType;
		RefCountedMT()
        {
            pCount_ = static_cast<CountPtrType>(
                SmallObject<ThreadingModel>::operator new(
                    sizeof(unsigned int)));
            assert(pCount_);
            *pCount_ = 1;
        }

		// MWCW lacks template friends, hence the following kludge
        // BK: Without the dummy-Parameter, the VC 6.0 won't compile the
		// copy ctor (error C2535: 'member function already defined or declared')
		// Adding the dummy-Parameter results in two things:
		// 1. The VC doesn't complain about the copy-ctor
		// 2. The VC *always* calls the template-copy-ctor, whether *this and rhs
		// have the same type or not.
		template <typename P1>
        RefCountedMT(const RefCountedMT<P1, ThreadingModel>& rhs, int dummy=0)
        : pCount_(reinterpret_cast<const RefCountedMT<P, ThreadingModel>&>(rhs).pCount_)
        {}


		RefCountedMT(const RefCountedMT& rhs)
        : pCount_(rhs.pCount_)
        {}



        P Clone(const P& val)
        {
			ThreadingModel::template In<RefCountedMT>::AtomicIncrement(*pCount_);
            return val;
        }

        bool Release(const P&)
        {
            if (!ThreadingModel::template In<RefCountedMT>::AtomicDecrement(*pCount_))
			{
				SmallObject<ThreadingModel>::operator delete(
                        const_cast<CountType *>(pCount_),
                        sizeof(*pCount_));
				return true;
			}
			return false;
        }

        void Swap(RefCountedMT& rhs)
        { std::swap(pCount_, rhs.pCount_); }

        enum { destructiveCopy = false };

    private:
        // Data
        //volatile unsigned int* pCount_;
		CountPtrType pCount_;
    };

	template <class ThreadingModel>
	struct RefCountedMTWrapper
	{
		template <class U>
		struct In
		{
			typedef RefCountedMT<U, ThreadingModel> type;
		};
	};
////////////////////////////////////////////////////////////////////////////////
// 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&)
        {}
    };

	struct COMRefCountedWrapper
	{
		template <class T>
		struct In
		{
			typedef COMRefCounted<T> type;
		};
	};
////////////////////////////////////////////////////////////////////////////////
// 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 };
    };

	struct DeepCopyWrapper
	{
		template <class T>
		struct In
		{
			typedef DeepCopy<T> type;
		};
	};
////////////////////////////////////////////////////////////////////////////////
// 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&)
        {	typedef Private::RefLinkedBase MyBase;
			return this->MyBase::Release();
		}
    };

	struct RefLinkedWrapper
	{
		template <class T>
		struct In
		{
			typedef RefLinked<T> type;
		};
	};
////////////////////////////////////////////////////////////////////////////////
// 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;
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -