/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#ifndef CM_AUTO_PTR_HXX
#define CM_AUTO_PTR_HXX

#include <cmConfigure.h>

#ifdef CMake_HAVE_CXX_AUTO_PTR

#include <memory>
#define CM_AUTO_PTR std::auto_ptr

#else

#define CM_AUTO_PTR cm::auto_ptr

// The HP compiler cannot handle the conversions necessary to use
// auto_ptr_ref to pass an auto_ptr returned from one function
// directly to another function as in use_auto_ptr(get_auto_ptr()).
// We instead use const_cast to achieve the syntax on those platforms.
// We do not use const_cast on other platforms to maintain the C++
// standard design and guarantee that if an auto_ptr is bound
// to a reference-to-const then ownership will be maintained.
#if defined(__HP_aCC)
#define cm_AUTO_PTR_REF 0
#define cm_AUTO_PTR_CONST const
#define cm_AUTO_PTR_CAST(a) cast(a)
#else
#define cm_AUTO_PTR_REF 1
#define cm_AUTO_PTR_CONST
#define cm_AUTO_PTR_CAST(a) a
#endif

// In C++11, clang will warn about using dynamic exception specifications
// as they are deprecated.  But as this class is trying to faithfully
// mimic std::auto_ptr, we want to keep the 'throw()' decorations below.
// So we suppress the warning.
#if defined(__clang__) && defined(__has_warning)
#if __has_warning("-Wdeprecated")
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
#endif

namespace cm {

template <class X>
class auto_ptr;

#if cm_AUTO_PTR_REF
namespace detail {
// The auto_ptr_ref template is supposed to be a private member of
// auto_ptr but Borland 5.8 cannot handle it.  Instead put it in
// a private namespace.
template <class Y>
struct auto_ptr_ref
{
  Y* p_;

  // The extra constructor argument prevents implicit conversion to
  // auto_ptr_ref from auto_ptr through the constructor.  Normally
  // this should be done with the explicit keyword but Borland 5.x
  // generates code in the conversion operator to call itself
  // infinately.
  auto_ptr_ref(Y* p, int)
    : p_(p)
  {
  }
};
}
#endif

/** C++98 Standard Section 20.4.5 - Template class auto_ptr.  */
template <class X>
class auto_ptr
{
#if !cm_AUTO_PTR_REF
  template <typename Y>
  static inline auto_ptr<Y>& cast(auto_ptr<Y> const& a)
  {
    return const_cast<auto_ptr<Y>&>(a);
  }
#endif

  /** The pointer to the object held.  */
  X* x_;

public:
  /** The type of object held by the auto_ptr.  */
  typedef X element_type;

  /** Construct from an auto_ptr holding a compatible object.  This
      transfers ownership to the newly constructed auto_ptr.  */
  template <class Y>
  auto_ptr(auto_ptr<Y> cm_AUTO_PTR_CONST& a) throw()
    : x_(cm_AUTO_PTR_CAST(a).release())
  {
  }

  /** Assign from an auto_ptr holding a compatible object.  This
      transfers ownership to the left-hand-side of the assignment.  */
  template <class Y>
  auto_ptr& operator=(auto_ptr<Y> cm_AUTO_PTR_CONST& a) throw()
  {
    this->reset(cm_AUTO_PTR_CAST(a).release());
    return *this;
  }

  /**
   * Explicitly construct from a raw pointer.  This is typically
   * called with the result of operator new.  For example:
   *
   *   auto_ptr<X> ptr(new X());
   */
  explicit auto_ptr(X* p = CM_NULLPTR) throw()
    : x_(p)
  {
  }

  /** Construct from another auto_ptr holding an object of the same
      type.  This transfers ownership to the newly constructed
      auto_ptr.  */
  auto_ptr(auto_ptr cm_AUTO_PTR_CONST& a) throw()
    : x_(cm_AUTO_PTR_CAST(a).release())
  {
  }

  /** Assign from another auto_ptr holding an object of the same type.
      This transfers ownership to the newly constructed auto_ptr.  */
  auto_ptr& operator=(auto_ptr cm_AUTO_PTR_CONST& a) throw()
  {
    this->reset(cm_AUTO_PTR_CAST(a).release());
    return *this;
  }

  /** Destruct and delete the object held.  */
  ~auto_ptr() throw()
  {
    // Assume object destructor is nothrow.
    delete this->x_;
  }

  /** Dereference and return a reference to the object held.  */
  X& operator*() const throw() { return *this->x_; }

  /** Return a pointer to the object held.  */
  X* operator->() const throw() { return this->x_; }

  /** Return a pointer to the object held.  */
  X* get() const throw() { return this->x_; }

  /** Return a pointer to the object held and reset to hold no object.
      This transfers ownership to the caller.  */
  X* release() throw()
  {
    X* x = this->x_;
    this->x_ = CM_NULLPTR;
    return x;
  }

  /** Assume ownership of the given object.  The object previously
      held is deleted.  */
  void reset(X* p = 0) throw()
  {
    if (this->x_ != p) {
      // Assume object destructor is nothrow.
      delete this->x_;
      this->x_ = p;
    }
  }

  /** Convert to an auto_ptr holding an object of a compatible type.
      This transfers ownership to the returned auto_ptr.  */
  template <class Y>
  operator auto_ptr<Y>() throw()
  {
    return auto_ptr<Y>(this->release());
  }

#if cm_AUTO_PTR_REF
  /** Construct from an auto_ptr_ref.  This is used when the
      constructor argument is a call to a function returning an
      auto_ptr.  */
  auto_ptr(detail::auto_ptr_ref<X> r) throw()
    : x_(r.p_)
  {
  }

  /** Assign from an auto_ptr_ref.  This is used when a function
      returning an auto_ptr is passed on the right-hand-side of an
      assignment.  */
  auto_ptr& operator=(detail::auto_ptr_ref<X> r) throw()
  {
    this->reset(r.p_);
    return *this;
  }

  /** Convert to an auto_ptr_ref.  This is used when a function
      returning an auto_ptr is the argument to the constructor of
      another auto_ptr.  */
  template <class Y>
  operator detail::auto_ptr_ref<Y>() throw()
  {
    return detail::auto_ptr_ref<Y>(this->release(), 1);
  }
#endif
};

} // namespace cm

// Undo warning suppression.
#if defined(__clang__) && defined(__has_warning)
#if __has_warning("-Wdeprecated")
#pragma clang diagnostic pop
#endif
#endif

#endif

#endif
