//auto_ptr在C++11中被unique_ptr替代,在GNU_STL中现在放在backward/auto_ptr中,可以访问但是不建议使用

#include<new>
#ifndef _NANXING_AUTO_PTR_H_
#define _NANXING_AUTO_PTR_H_

namespace nanxing
{
    template<typename _Ptr>
    struct auto_ptr_ref                       //作为一个中继
    {
        _Ptr* point;
        explicit auto_ptr_ref(_Ptr* _p):point(_p){}
    };
    template<typename _Ptr>
    class auto_ptr
    {
    private:
        _Ptr * point;               //auto_ptr中保留的原始指针
    public:
    //这里的_Ptr实际上都不是很需要,C++11之后能进行模板类型推导
        explicit auto_ptr(_Ptr* _p=0)throw():point(_p){}                  
        auto_ptr(auto_ptr<_Ptr>& _p)throw():point(_p.release()){}

        auto_ptr(auto_ptr<_Ptr>&& _p)throw(){}                     //移动构造函数

        //当然这里的this也是没必要的,只是为了明确一下到底是谁的release
        auto_ptr<_Ptr>& operator=(auto_ptr<_Ptr>& _p){                  //返回对应的引用是为了能够链式赋值
            if(_p!=this)
            {
                delete this->point;         //释放当前的指针指向的空间
            }
            this->point=_p.release();
            return *this;
        }

        _Ptr* release()
        {
            _Ptr* tmp=point;
            point=nullptr;
            return tmp;
        }
#ifdef _ES_UNSAFE_
        _Ptr* get() const
        {
            return point;
        }
#endif
        void reset(_Ptr* _p=nullptr)throw()
        {
            if(_p!=point)
            {
                delete point;
            }
            point=_p;
        }

        //在GNU_STL中还有两个类型转换运算符的定义
        operator auto_ptr_ref<_Ptr>()             //从auto_ptr->auto_ptr_ref 的定义
        {
            return auto_ptr_ref<_Ptr>(this->release());
        }

        operator auto_ptr<_Ptr>()                       //类型转换运算符
        {
            return auto_ptr<_Ptr>(this->release());
        }

        ~auto_ptr()
        {
            if(point!=nullptr)
            {
                delete point;
            }
        }


    };
}

#endif