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

📄 smartptr.h

📁 loki库的源代码。loki库是以模板技术和面向对象技术为基础的c++类库。
💻 H
📖 第 1 页 / 共 3 页
字号:
        static bool Release(const P&)
        { return true; }

        static void Swap(DestructiveCopy&)
        {}

        enum { destructiveCopy = true };
    };
    struct DestructiveCopyWrapper
	{
		template <class T>
		struct In
		{
			typedef DestructiveCopy<T> type;
		};
	};
////////////////////////////////////////////////////////////////////////////////
// class template NoCopy
// Implementation of the OwnershipPolicy used by SmartPtr
// Implements a policy that doesn't allow copying objects
////////////////////////////////////////////////////////////////////////////////

    template <class P>
    class NoCopy
    {
    public:
        NoCopy()
        {}

        template <class P1>
        NoCopy(const NoCopy<P1>&)
        {}

        static P Clone(const P&)
        {
            STATIC_CHECK(false, This_Policy_Disallows_Value_Copying);
        }

        static bool Release(const P&)
        { return true; }

        static void Swap(NoCopy&)
        {}

        enum { destructiveCopy = false };
    };

	struct NoCopyWrapper
	{
		template <class T>
		struct In
		{
			typedef NoCopy<T> type;
		};
	};
////////////////////////////////////////////////////////////////////////////////
// class template AllowConversion
// Implementation of the ConversionPolicy used by SmartPtr
// Allows implicit conversion from SmartPtr to the pointee type
////////////////////////////////////////////////////////////////////////////////

    struct AllowConversion
    {
        enum { allow = true };

        void Swap(AllowConversion&)
        {}
    };

////////////////////////////////////////////////////////////////////////////////
// class template DisallowConversion
// Implementation of the ConversionPolicy used by SmartPtr
// Does not allow implicit conversion from SmartPtr to the pointee type
// You can initialize a DisallowConversion with an AllowConversion
////////////////////////////////////////////////////////////////////////////////

    struct DisallowConversion
    {
        DisallowConversion()
        {}

        DisallowConversion(const AllowConversion&)
        {}

        enum { allow = false };

        void Swap(DisallowConversion&)
        {}
    };

////////////////////////////////////////////////////////////////////////////////
// class template NoCheck
// Implementation of the CheckingPolicy used by SmartPtr
// Well, it's clear what it does :o)
////////////////////////////////////////////////////////////////////////////////

    template <class P>
    struct NoCheck
    {
        NoCheck()
        {}

        template <class P1>
        NoCheck(const NoCheck<P1>&)
        {}

        static void OnDefault(const P&)
        {}

        static void OnInit(const P&)
        {}

        static void OnDereference(const P&)
        {}

        static void Swap(NoCheck&)
        {}
    };

	struct NoCheckWrapper
	{
		template <class T>
		struct In
		{
			typedef NoCheck<T> type;
		};
	};
////////////////////////////////////////////////////////////////////////////////
// class template AssertCheck
// Implementation of the CheckingPolicy used by SmartPtr
// Checks the pointer before dereference
////////////////////////////////////////////////////////////////////////////////

    template <class P>
    struct AssertCheck
    {
        AssertCheck()
        {}

        template <class P1>
        AssertCheck(const AssertCheck<P1>&)
        {}

        template <class P1>
        AssertCheck(const NoCheck<P1>&)
        {}

        static void OnDefault(const P&)
        {}

        static void OnInit(const P&)
        {}

        static void OnDereference(P val)
        { assert(val); }

        static void Swap(AssertCheck&)
        {}
    };

	struct AssertCheckWrapper
	{
		template <class T>
		struct In {typedef AssertCheck<T> type;};
	};
////////////////////////////////////////////////////////////////////////////////
// class template AssertCheckStrict
// Implementation of the CheckingPolicy used by SmartPtr
// Checks the pointer against zero upon initialization and before dereference
// You can initialize an AssertCheckStrict with an AssertCheck
////////////////////////////////////////////////////////////////////////////////

    template <class P>
    struct AssertCheckStrict
    {
        AssertCheckStrict()
        {}

        template <class U>
        AssertCheckStrict(const AssertCheckStrict<U>&)
        {}

        template <class U>
        AssertCheckStrict(const AssertCheck<U>&)
        {}

        template <class P1>
        AssertCheckStrict(const NoCheck<P1>&)
        {}

        static void OnDefault(P val)
        { assert(val); }

        static void OnInit(P val)
        { assert(val); }

        static void OnDereference(P val)
        { assert(val); }

        static void Swap(AssertCheckStrict&)
        {}
    };

	struct AssertCheckStrictWrapper
	{
		template <class T>
		struct In
		{
			typedef AssertCheckStrict<T> type;
		};
	};
////////////////////////////////////////////////////////////////////////////////
// class NullPointerException
// Used by some implementations of the CheckingPolicy used by SmartPtr
////////////////////////////////////////////////////////////////////////////////

    struct NullPointerException : public std::runtime_error
    {
        NullPointerException() : std::runtime_error("")
        { }
        const char* what() const throw()
        { return "Null Pointer Exception"; }
    };

////////////////////////////////////////////////////////////////////////////////
// class template RejectNullStatic
// Implementation of the CheckingPolicy used by SmartPtr
// Checks the pointer upon initialization and before dereference
////////////////////////////////////////////////////////////////////////////////

    template <class P>
    struct RejectNullStatic
    {
        RejectNullStatic()
        {}

        template <class P1>
        RejectNullStatic(const RejectNullStatic<P1>&)
        {}

        template <class P1>
        RejectNullStatic(const NoCheck<P1>&)
        {}

        template <class P1>
        RejectNullStatic(const AssertCheck<P1>&)
        {}

        template <class P1>
        RejectNullStatic(const AssertCheckStrict<P1>&)
        {}

        static void OnDefault(const P&)
        {
            CompileTimeError<false>
                ERROR_This_Policy_Does_Not_Allow_Default_Initialization;
        }

        static void OnInit(const P& val)
        { if (!val) throw NullPointerException(); }

        static void OnDereference(const P& val)
        { if (!val) throw NullPointerException(); }

        static void Swap(RejectNullStatic&)
        {}
    };

	struct RejectNullStaticWrapper
	{
		template <class T>
		struct In
		{
			typedef RejectNullStatic<T> type;
		};
	};
////////////////////////////////////////////////////////////////////////////////
// class template RejectNull
// Implementation of the CheckingPolicy used by SmartPtr
// Checks the pointer before dereference
////////////////////////////////////////////////////////////////////////////////

    template <class P>
    struct RejectNull
    {
        RejectNull()
        {}

        template <class P1>
        RejectNull(const RejectNull<P1>&)
        {}

        static void OnInit(P val)
        { if (!val) throw NullPointerException(); }

        static void OnDefault(P val)
        { OnInit(val); }

        void OnDereference(P val)
        { OnInit(val); }

        void Swap(RejectNull&)
        {}
    };

	struct RejectNullWrapper
	{
		template <class T>
		struct In
		{
			typedef RejectNull<T> type;
		};
	};

////////////////////////////////////////////////////////////////////////////////
// class template RejectNullStrict
// Implementation of the CheckingPolicy used by SmartPtr
// Checks the pointer upon initialization and before dereference
////////////////////////////////////////////////////////////////////////////////

    template <class P>
    struct RejectNullStrict
    {
        RejectNullStrict()
        {}

        template <class P1>
        RejectNullStrict(const RejectNullStrict<P1>&)
        {}

        template <class P1>
        RejectNullStrict(const RejectNull<P1>&)
        {}

        static void OnInit(P val)
        { if (!val) throw NullPointerException(); }

        void OnDereference(P val)
        { OnInit(val); }

        void Swap(RejectNullStrict&)
        {}
    };

	struct RejectNullStrictWrapper
	{
		template <class T>
		struct In
		{
			typedef RejectNullStrict<T> type;
		};
	};
////////////////////////////////////////////////////////////////////////////////
// class template ByRef
// Transports a reference as a value
// Serves to implement the Colvin/Gibbons trick for SmartPtr
////////////////////////////////////////////////////////////////////////////////

    template <class T>
    class ByRef
    {
    public:
        ByRef(T& v) : value_(v) {}
        operator T&() { return value_; }
        // gcc doesn't like this:
        // operator const T&() const { return value_; }
    private:
        T& value_;
    };

////////////////////////////////////////////////////////////////////////////////
// class template SmartPtr (declaration)
// The reason for all the fuss above
////////////////////////////////////////////////////////////////////////////////

    template
    <
        typename T,
        class OwnershipPolicy = RefCountedWrapper,
        class ConversionPolicy = DisallowConversion,
        class CheckingPolicy = AssertCheckWrapper,
        class StoragePolicy = DefaultSPStorageWrapper
    >
    class SmartPtr;


////////////////////////////////////////////////////////////////////////////////
// class template SmartPtr (definition)
////////////////////////////////////////////////////////////////////////////////

namespace Private
{
	template <class T, class Ow, class Con, class Check, class Stor>
	struct SmartPtrImpl
	{
		struct Dummy{};
		typedef typename ApplyInnerType<Stor, T>::type TempType;
		typedef VC_Base_Workaround<TempType, Dummy> sttype;
		// VC 6.0 will emit an "Error C2516. : is not a legal base class"
		// if one tries to use TempType as base class for SmartPtr.
		// Don't know why the compiler is happy with this workaround
		typedef sttype::LeftBase Storage;
		typedef Storage::PointerType PointerType;
		typedef Storage::StoredType StoredType;
		typedef Storage::ReferenceType ReferenceType;

		typedef typename ApplyInnerType<Ow, PointerType>::type Temp2Type;
		typedef typename ApplyInnerType<Check, StoredType>::type Temp3Type;

		typedef VC_Base_Workaround<Temp2Type, Dummy> owtype;
		typedef owtype::LeftBase Owner;

		typedef VC_Base_Workaround<Temp3Type, Dummy> chtype;
		typedef chtype::LeftBase Checking;

		typedef Con Conversion;
	};
}
    template
    <
        typename T,
        class OwnershipPolicy,
        class ConversionPolicy,
        class CheckingPolicy,
        class StoragePolicy
    >
    class SmartPtr
		: public Private::SmartPtrImpl<T, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy>::Storage
        , public Private::SmartPtrImpl<T, OwnershipPolicy, ConversionPolicy,CheckingPolicy, StoragePolicy>::Owner
        , public Private::SmartPtrImpl<T, OwnershipPolicy, ConversionPolicy,CheckingPolicy, StoragePolicy>::Checking
        , public Private::SmartPtrImpl<T, OwnershipPolicy, ConversionPolicy,CheckingPolicy, StoragePolicy>::Conversion
    {
    public:
        typedef typename Private::SmartPtrImpl
		<
			T, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy
		>::Storage SP;
		typedef SP::PointerType PointerType;
        typedef SP::StoredType StoredType;
        typedef SP::ReferenceType ReferenceType;

		typedef typename Private::SmartPtrImpl
		<
			T, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy
		>::Owner OP;
        typedef typename Private::SmartPtrImpl
		<
			T, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy
		>::Checking KP;

		typedef ConversionPolicy CP;
        typedef typename Select
		<
			OP::destructiveCopy,
			SmartPtr, const SmartPtr
		>::Result CopyArg;

		typedef typename Select
		<
			OP::destructiveCopy,
			NullType, StoredType
		>::Result WorkaroundType;

        // i think the following two ctors have an exception-safety problem
		// in the original version. If KP throws one can't release the resources
		// which were possibly allocated by SP and/or OP.
		// don't know if my solution works.
		SmartPtr()
        {
			try
			{
				KP::OnDefault(GetImpl(*this));
			}
			catch(...)
			{
				if (OP::Release(GetImpl(*static_cast<SP*>(this))))
    			{
    				SP::Destroy();
    			}
				throw;
			}
		}

        SmartPtr(const StoredType& p) : SP(p)
        {
			try
			{
				KP::OnInit(GetImpl(*this));
			}
			catch(...)
			{
				if (OP::Release(GetImpl(*static_cast<SP*>(this))))
    			{
    				SP::Destroy();
    			}
				throw;
			}

		}

⌨️ 快捷键说明

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