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

📄 smartptr.h

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


////////////////////////////////////////////////////////////////////////////////
// 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); (void)val; }

        static void Swap(AssertCheck&)
        {}
    };

////////////////////////////////////////////////////////////////////////////////
// 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&)
        {}
    };

////////////////////////////////////////////////////////////////////////////////
// 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&)
        {
            STATIC_CHECK(false, 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&)
        {}
    };

////////////////////////////////////////////////////////////////////////////////
// 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&)
        {}        
    };

////////////////////////////////////////////////////////////////////////////////
// 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&)
        {}        
    };

////////////////////////////////////////////////////////////////////////////////
// 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:
        ByRef(const ByRef &);
        ByRef& operator=(const ByRef &);

        T& value_;
    };


////////////////////////////////////////////////////////////////////////////////
// class template WrapTemplate (definition)
// suggested workaround for vc7 limitation with template template arguments
////////////////////////////////////////////////////////////////////////////////
template<template<typename> class C>
struct WrapTemplate
{
    template<typename T>
    struct In
    {
        typedef C<T> type;
    };

    // VC7 BUG - cannot access protected typedef
    template<typename T>
    struct PointerType : private C<T>
    {
        typedef typename C<T>::PointerType type;
    };

    // VC7 BUG - cannot access protected typedef
    template<typename T>
    struct StoredType : private C<T>
    {
        typedef typename C<T>::StoredType type;
    };
};

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

    template
    <
        typename T,
        class OwnershipPolicy = WrapTemplate<RefCounted>,
        class ConversionPolicy = DisallowConversion,
        class CheckingPolicy = WrapTemplate<AssertCheck>,
        class StoragePolicy = WrapTemplate<DefaultSPStorage>
    >
    class SmartPtr;

////////////////////////////////////////////////////////////////////////////////
// class template SmartPtrDef (definition)
// this class added to adjust the ported SmartPtr to the original one.
// instead of writing SmartPtr<T,OP,CP,KP,SP> write SmartPtrDef<T,OP,CP,KP,SP>::type
////////////////////////////////////////////////////////////////////////////////

    template
    <
        typename T,
        template <class> class OwnershipPolicy = RefCounted,
        class ConversionPolicy = DisallowConversion,
        template <class> class CheckingPolicy = AssertCheck,
        template <class> class StoragePolicy = DefaultSPStorage
    >
    struct SmartPtrDef
    {
        typedef SmartPtr
        <
            T,
            WrapTemplate<OwnershipPolicy>,
            ConversionPolicy,
            WrapTemplate<CheckingPolicy>,
            WrapTemplate<StoragePolicy>
        >
        type;
    };

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

    template
    <
        typename T,
        class OwnershipPolicy,
        class ConversionPolicy,
        class CheckingPolicy,
        class StoragePolicy
    >
    class SmartPtr
        : public StoragePolicy::In<T>::type
        , public OwnershipPolicy::In<typename StoragePolicy::template PointerType<T>::type>::type
        , public CheckingPolicy ::In<typename StoragePolicy::template StoredType<T>::type>::type
        , public ConversionPolicy
    {
        typedef typename StoragePolicy::template In<T>::type SP;
        typedef typename OwnershipPolicy::template In<typename SP::PointerType>::type OP;
        typedef typename CheckingPolicy::template  In<typename SP::StoredType>::type  KP;
        typedef ConversionPolicy CP;
        
        // VC7 bug
        enum { OP_destructiveCopy = OP::destructiveCopy };
        enum { CP_allow = CP::allow };

    public:
        typedef typename SP::PointerType PointerType;
        typedef typename SP::StoredType StoredType;
        typedef typename SP::ReferenceType ReferenceType;
        

        typedef typename Select
        <
            OP_destructiveCopy, 
            SmartPtr, 
            const SmartPtr
        >
        ::Result CopyArg;
    
   private:
        void OnKPReject()
        {
            if (OP::Release(GetImpl(*static_cast<SP*>(this)), true))
            {
                // if KP::IsDestructive(GetImpl(*this))
                // call SP::Destroy() ?
            }
        }

        class SmartPtrGuard
        {
        public:
            typedef void (SmartPtr::*action_t)();

            SmartPtrGuard(SmartPtr &sptr, action_t action)
                : sptr_(sptr), action_(action), guard_(true)
            {}

            void Dismiss() { guard_ = false; }

            ~SmartPtrGuard()
            { if (guard_) (sptr_.*action_)(); }

        private:
            SmartPtrGuard(const SmartPtrGuard &);
            SmartPtrGuard& operator=(const SmartPtrGuard &);

        private:
            SmartPtr    &sptr_;
            action_t    action_;
            bool        guard_;
        };

    public:

        SmartPtr()
        { 
            SmartPtrGuard KPGuard(*this, &SmartPtr::OnKPReject);
            KP::OnDefault(GetImpl(*this)); 
            KPGuard.Dismiss();
        }
        
        //
        // This constructor has exception safety problem
        // If OP constructor throw - p might be leaked
        // One solution is to add method to OP named OnInit with the following usage:
        // OP::OnInit(GetImpl(*this), implicit_cast<SP&>(*this)); 
        // The OP default constructor will have no throw guaranty 
        // and the OP::OnInit will decide if destroy should be invoked upon exception
        //
        SmartPtr(const StoredType& p) : SP(p)
        { 
            //
            // The following try catch only solve part of the exception safety problem.
            // The solution might be wrong because KP might reject illegal pointers (not destructible via destroy like null com pointer).
            // The complete solution might involve more tight connections between KP, OP and SP.
            //
            SmartPtrGuard KPGuard(*this, &SmartPtr::OnKPReject);
            KP::OnInit(GetImpl(*this)); 
            KPGuard.Dismiss();
        }
        
        SmartPtr(CopyArg& rhs)
        : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
        { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }

        template
        <

⌨️ 快捷键说明

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