SmartPtr实作

#ifndef _KOK_SMARTPTR_H_
#define _KOK_SMARTPTR_H_

#pragma once

#include <cstdlib>
#include <assert.h>
#include <algorithm>

namespace KOK
{
    template<class P>
    class CheckAssert
    {
    protected:
        void OnRef(const P& pointer)
        {
            assert(pointer !=NULL);
        }
        void OnDeRef(const P& pointer)
        {
            assert(pointer !=NULL);
        }
        void Swap(CheckAssert&){};

        CheckAssert(){};
        CheckAssert(const CheckAssert&){};

        template<class U>
        CheckAssert(const CheckAssert<U>&){};
    };
    template<class T>
    class DefaultStorage
    {
    public:
        typedef T* StoredType;
        typedef T* PointerType;
        typedef T& RefType;
    protected:
        DefaultStorage():pointee_(Default()){};
        DefaultStorage(StoredType pType):pointee_(pType){};
        DefaultStorage(const DefaultStorage& pType){};

        template<class H>
        DefaultStorage(const DefaultStorage<H>& pType){};

        void Swap(DefaultStorage& other)
        {
            std::swap(pointee_, other.pointee_);
        };
        void Destroy()
        {
            delete pointee_;
        };
        static StoredType Default()
        {
            return 0;
        }
    public:
        RefType operator *() const
        {
            return *pointee_;
        }
        PointerType operator ->() const
        {
            return pointee_;
        }
        template<class U>
        friend typename DefaultStorage<U>::StoredType GetPtrImpl(const DefaultStorage<U>& wrap);

        template<class U>
        friend typename DefaultStorage<U>::RefType GetRef(const DefaultStorage<U>& wrap);

        template<class U>
        friend typename DefaultStorage<U>::StoredType& GetPtrRef(DefaultStorage<U>& wrap);

        template<class U>
        friend typename const DefaultStorage<U>::StoredType& GetPtrRef(const DefaultStorage<U>& wrap);

    private:
        StoredType pointee_;

    };
    template<class U>
    inline typename DefaultStorage<U>::StoredType GetPtrImpl(const DefaultStorage<U>& wrap)
    {
        return wrap.pointee_;
    };
    template<class U>
    inline typename DefaultStorage<U>::RefType GetRef(const DefaultStorage<U>& wrap)
    {
        return *wrap.pointee_;
    };
    template<class U>
    inline typename DefaultStorage<U>::StoredType& GetPtrRef(DefaultStorage<U>& wrap)
    {
        return wrap.pointee_;
    };
    template<class U>
    inline typename const DefaultStorage<U>::StoredType& GetPtrRef(const DefaultStorage<U>& wrap)
    {
        return wrap.pointee_;
    };
    template<class P>
    class RefCount
    {
    private:
        unsigned int* count_;
    protected:
        RefCount(const RefCount& other):count_(other.count_){};
        template<class P1>
        RefCount(const RefCount<P1>& other):count_(reinterpret_cast<const RefCount&>(other).count_){};

        RefCount():count_(new unsigned int(1))
        {
            assert(count_ != NULL);
        };
        P Clone(const P& val)
        {
            ++*count_;
            return val;
        }
        bool Release()
        {
            if(--*count_ == 0)
            {
                delete count_;
                return true;
            }
            return false;
        };
        void Reset()
        {
            *count_ = 1;
        };
        void Swap(RefCount& other)
        {
            std::swap(count_, other.count_);
        };
        enum {destroyCopy = false};
    };

    template<class T,
        template<class> class StoragePolicy = DefaultStorage,
        template<class> class OwnershipPolicy = RefCount,
        template<class> class CheckErrorPolicy = CheckAssert>
    class SmartPtr : public StoragePolicy<T>,
        public OwnershipPolicy<typename StoragePolicy<T>::StoredType>,
        public CheckErrorPolicy<typename StoragePolicy<T>::StoredType>
    {
    public:
        typedef typename StoragePolicy<T>::StoredType StoredType;
        typedef typename StoragePolicy<T>::PointerType PointerType;
        typedef typename StoragePolicy<T>::RefType RefType;

        template<bool B, class X, class Y>
        struct Select
        {
        };
        template<class X, class Y>
        struct Select<false, X, Y>
        {
            typedef Y type;
        };
        template<class X, class Y>
        struct Select<true, X, Y>
        {
            typedef Y type;
        };

    private:
        typedef StoragePolicy<T> SP;
        typedef OwnershipPolicy<StoredType> OP;
        typedef CheckErrorPolicy<StoredType> CP;

    public:
        typedef typename Select<OP::destroyCopy, SmartPtr<T, StoragePolicy, OwnershipPolicy, CheckErrorPolicy>, const SmartPtr<T, StoragePolicy, OwnershipPolicy, CheckErrorPolicy> >::type CpyArg;
        SmartPtr(StoredType ptr):SP(ptr)
        {
            assert(NULL != ptr);
        };

        SmartPtr()
        {
        };

        SmartPtr(CpyArg& copyPtr):SP(copyPtr), OP(copyPtr), CP(copyPtr)
        {
            GetPtrRef(*this) = OP::Clone(GetPtrImpl(copyPtr));
        };
        template<class T1,
            template<class> class SP1,
            template<class> class OP1,
            template<class> class CP1>
        SmartPtr(SmartPtr<T1, SP1, OP1, CP1>& copyPtr):SP(copyPtr), OP(copyPtr), CP(copyPtr)
        {
            GetPtrRef(*this) = OP::Clone(GetPtrImpl(copyPtr));
        };
        template<class T1,
            template<class> class SP1,
            template<class> class OP1,
            template<class> class CP1>
        SmartPtr(const SmartPtr<T1, SP1, OP1, CP1>& copyPtr):SP(copyPtr), OP(copyPtr), CP(copyPtr)
        {
            GetPtrRef(*this) = OP::Clone(GetPtrImpl(copyPtr));
        };
        RefType operator *()
        {
            CP::OnDeRef(GetPtrImpl(*this));
            return SP::operator*();
        };
        PointerType operator ->()
        {
            CP::OnDeRef(GetPtrImpl(*this));
            return SP::operator->();
        };
        template<class T1,
            template<class> class SP1,
            template<class> class OP1,
            template<class> class CP1>
        SmartPtr& operator =(SmartPtr<T1, SP1, OP1, CP1>& rhs)
        {
            SmartPtr temp(rhs);
            temp.Swap(*this);
            return *this;
        };
        template<class T1,
            template<class> class SP1,
            template<class> class OP1,
            template<class> class CP1>
        SmartPtr& operator =(const SmartPtr<T1, SP1, OP1, CP1>& rhs)
        {
            SmartPtr temp(rhs);
            temp.Swap(*this);
            return *this;
        };
        SmartPtr& operator =(CpyArg& rhs)
        {
            SmartPtr temp(rhs);
            temp.Swap(*this);
            return *this;
        };
        void Swap(SmartPtr& other)
        {
            OP::Swap(other);
            SP::Swap(other);
            CP::Swap(other);
        };
        ~SmartPtr()
        {
            if(OP::Release())
                SP::Destroy();
        };
    private:
        class Tester
        {
            void operator delete(void*);
        };
    public:
        operator Tester*()
        {
            if(GetPtrImpl(*this) == 0)
                return 0;
            static Tester test;
            return &test;
        };
        template<class T1,
            template<class> class SP1,
            template<class> class OP1,
            template<class> class CP1>
        friend void Release(SmartPtr<T1, SP1, OP1, CP1>& des, typename SmartPtr<T1, SP1, OP1, CP1>::StoredType& p);

        template<class U>
        friend inline bool operator ==(const SmartPtr& lhs, const U* rhs)
        {
            return GetPtrImpl(lhs) == rhs;
        };
        template<class U>
        friend inline bool operator ==(const U* lhs, const SmartPtr& rhs)
        {
            return rhs == lhs;
        };
        friend inline bool operator ==(const SmartPtr& lhs, const T* rhs)
        {
            return GetPtrImpl(lhs) == rhs;
        };
        friend inline bool operator ==(const T* lhs, const SmartPtr& rhs)
        {
            return rhs == lhs;
        };

        template<class U>
        friend inline bool operator !=(const SmartPtr& lhs, const U* rhs)
        {
            return !(lhs == rhs);
        };
        template<class U>
        friend inline bool operator !=(const U* lhs, const SmartPtr& rhs)
        {
            return rhs != lhs;
        };
        friend inline bool operator !=(const SmartPtr& lhs, const T* rhs)
        {
            return !(lhs == rhs);
        };
        friend inline bool operator !=(const T* lhs, const SmartPtr& rhs)
        {
            return rhs != lhs;
        };

    };

    template<class T1,
        template<class> class SP1,
        template<class> class OP1,
        template<class> class CP1>
    inline void Release(SmartPtr<T1, SP1, OP1, CP1>& des, typename SmartPtr<T1, SP1, OP1, CP1>::StoredType& p)
    {
        p = GetPtrImpl(des);
        GetPtrRef(des) = SP1<T1>::Default();
    };
    template<class T1,
        template<class> class SP1,
        template<class> class OP1,
        template<class> class CP1,
    class T2,
        template<class> class SP2,
        template<class> class OP2,
        template<class> class CP2>
    inline bool operator ==(const SmartPtr<T1, SP1, OP1, CP1>& lhs, const SmartPtr<T2, SP2, OP2, CP2>& rhs)
    {
        return GetPtrImpl(lhs) == GetPtrImpl(rhs);
    };
    template<class T1,
        template<class> class SP1,
        template<class> class OP1,
        template<class> class CP1,
    class T2,
        template<class> class SP2,
        template<class> class OP2,
        template<class> class CP2>
    inline bool operator !=(const SmartPtr<T1, SP1, OP1, CP1>& lhs, const SmartPtr<T2, SP2, OP2, CP2>& rhs)
    {
        return !(lhs == rhs);
    };
}
#endif

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值