#pragma once
#ifndef _DEEPPTR
#define _DEEPPTR

#include "autoPointer.hpp"
#include "smartPointer.hpp"
//will simply take ownership from autoPtr
//will copy from smartpointer

template <typename T>
class deepPtr{
    T* _pointee;
public:
    deepPtr();
    explicit deepPtr(T * pointee);
    deepPtr(const deepPtr<T> &dp);
    deepPtr(deepPtr<T> &dp);
    deepPtr(smartPtr<T> &dp);
    deepPtr(autoPtr<T> &sp);
    ~deepPtr();
    deepPtr<T>& operator=(deepPtr<T>& sp);
    deepPtr<T>& operator=(autoPtr<T>& sp);
    deepPtr<T>& operator=(smartPtr<T>& sp);
    operator bool()const;
    T& operator*()const;
    T* operator->()const;
};

template <typename T>
deepPtr<T>::deepPtr()
{
    _pointee = 0;
}

template <typename T>
deepPtr<T>::deepPtr(T * pointee)
{
    _pointee = pointee;
}

template <typename T>
deepPtr<T>::deepPtr(const deepPtr<T> &dp)
{
}

template <typename T>
deepPtr<T>::deepPtr(deepPtr<T> &dp)
{
    _pointee = new T(*dp);
}

template <typename T>
deepPtr<T>::deepPtr(autoPtr<T> &dp)
{
    _pointee = dp._pointee;
    dp._pointee = 0;
}

template <typename T>
deepPtr<T>::deepPtr(smartPtr<T> &dp)
{
    _pointee = new T(*dp);
}

template <typename T>
deepPtr<T>::~deepPtr()
{
    delete _pointee;
}

template <typename T>
deepPtr<T>& deepPtr<T>::operator=(deepPtr<T>& sp)
{
        if(_pointee)
            delete _pointee;
        _pointee = new T(*sp);
    return *this;
}

template <typename T>
deepPtr<T>& deepPtr<T>::operator=(autoPtr<T>& sp)
{
        if(_pointee)
            delete _pointee;
        _pointee = sp._pointee;
        sp._pointee = 0;
    return *this;
}

template <typename T>
deepPtr<T>& deepPtr<T>::operator=(smartPtr<T>& sp)
{
    if(this != &sp)
    {
        if(_pointee)
            delete _pointee;
        _pointee = new T(*sp);
    }
    return *this;
}

template <typename T>
deepPtr<T>::operator bool()const
{
    return _pointee!=0;
}

template <typename T>
T& deepPtr<T>::operator*()const
{
    return *_pointee;
}

template <typename T>
T* deepPtr<T>::operator->()const
{
    return _pointee;
}


#endif
