/*
 * smart_pointer.h
 *
 * A very simple smart pointer type implementing deep copy.
 */
#ifndef SMART_POINTER_H
#define SMART_POINTER_H

template<typename T>
class smart_pointer
{
public:
   smart_pointer() = default;

   explicit smart_pointer(T* p) : ptr_{ p } {}

   smart_pointer(const smart_pointer& rhs) : ptr_{ copy(rhs) } {}

   ~smart_pointer() { delete ptr_; }

   smart_pointer& operator=(const smart_pointer& rhs) &
   {
      if (this != &rhs)
      {
	 T* ptr{ copy(rhs) };
	 delete ptr_;
	 ptr_ = ptr;
      }
      return *this;
   }

   T& operator*() const { return *ptr_; }
   T& operator*() { return *ptr_; }
      
   T* operator->() const { return ptr_; }
   T* operator->() { return ptr_; }

private:
   T* ptr_{ nullptr };

   T* copy(const smart_pointer& sp)
   {
      return sp.ptr_ ? new T{ *sp.ptr_ } : nullptr;
   }
};

#endif