text: /* gnu::unique_ptr, a simple std::unique_ptr replacement for C++03.
  
     Copyright (C) 2007-2020 Free Software Foundation, Inc.
  
     This file is part of GCC.
  
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
  
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
  
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
  
  /* gnu::unique_ptr defines a C++ owning smart pointer that exposes a
     subset of the std::unique_ptr API.
  
     In fact, when compiled with a C++11 compiler, gnu::unique_ptr
     actually _is_ std::unique_ptr.  When compiled with a C++03 compiler
     OTOH, it's an hand coded std::unique_ptr emulation that assumes
     code is correct and doesn't try to be too smart.
  
     This supports custom deleters, but not _stateful_ deleters, so you
     can't use those in C++11 mode either.  Only the managed pointer is
     stored in the smart pointer.  That could be changed; it simply
     wasn't found necessary.
  
     At the end of the file you'll find a gnu::unique_ptr partial
     specialization that uses a custom (stateless) deleter:
     gnu::unique_xmalloc_ptr.  That is used to manage pointers to
     objects allocated with xmalloc.
  
     The C++03 version was originally based on GCC 7.0's std::auto_ptr
     and then heavily customized to behave more like C++11's
     std::unique_ptr, but at this point, it no longer shares much at all
     with the original file.  But, that's the history and the reason for
     the copyright's starting year.
  
     The C++03 version lets you shoot yourself in the foot, since
     similarly to std::auto_ptr, the copy constructor and assignment
     operators actually move.  Also, in the name of simplicity, no
     effort is spent on using SFINAE to prevent invalid conversions,
     etc.  This is not really a problem, because the goal here is to
     allow code that would be correct using std::unique_ptr to be
     equally correct in C++03 mode, and, just as efficient.  If client
     code compiles correctly with a C++11 (or newer) compiler, we know
     we're not doing anything invalid by mistake.
  
     Usage notes:
  
     - Putting gnu::unique_ptr in standard containers is not supported,
       since C++03 containers are not move-aware (and our emulation
       relies on copy actually moving).
  
     - Since there's no nullptr in C++03, gnu::unique_ptr allows
       implicit initialization and assignment from NULL instead.
  
     - To check whether there's an associated managed object, all these
       work as expected:
  
        if (ptr)
        if (!ptr)
        if (ptr != NULL)
        if (ptr == NULL)
        if (NULL != ptr)
        if (NULL == ptr)
  */
  
  #ifndef GNU_UNIQUE_PTR_H
  #define GNU_UNIQUE_PTR_H 1
  
  #if __cplusplus >= 201103
  # include <memory>
  #endif
  
  namespace gnu
  {
  
  #if __cplusplus >= 201103
  
  /* In C++11 mode, all we need is import the standard
     std::unique_ptr.  */
  template<typename T> using unique_ptr = std::unique_ptr<T>;
  
  /* Pull in move as well.  */
  using std::move;
  
  #else /* C++11 */
  
  /* Default destruction policy used by gnu::unique_ptr when no deleter
     is specified.  Uses delete.  */
  
  template<typename T>
  struct default_delete
  {
    void operator () (T *ptr) const { delete ptr; }
  };
  
  /* Specialization for arrays.  Uses delete[].  */
  
  template<typename T>
  struct default_delete<T[]>
  {
    void operator () (T *ptr) const { delete [] ptr; }
  };
  
  namespace detail
  {
  /* Type used to support implicit construction from NULL:
  
       gnu::unique_ptr<foo> func (....)
       {
       return NULL;
       }
  
     and assignment from NULL:
  
       gnu::unique_ptr<foo> ptr (....);
       ...
       ptr = NULL;
  
    It is intentionally not defined anywhere.  */
  struct nullptr_t;
  
  /* Base class of our unique_ptr emulation.  Contains code common to
     both unique_ptr<T, D> and unique_ptr<T[], D>.  */
  
  template<typename T, typename D>
  class unique_ptr_base
  {
  public:
    typedef T *pointer;
    typedef T element_type;
    typedef D deleter_type;
  
    /* Takes ownership of a pointer.  P is a pointer to an object of
       element_type type.  Defaults to NULL.  */
    explicit unique_ptr_base (element_type *p = NULL) throw () : m_ptr (p) {}
  
    /* The "move" constructor.  Really a copy constructor that actually
       moves.  Even though std::unique_ptr is not copyable, our little
       simpler emulation allows it, because:
  
         - There are no rvalue references in C++03.  Our move emulation
         instead relies on copy/assignment moving, like std::auto_ptr.
         - RVO/NRVO requires an accessible copy constructor
    */
    unique_ptr_base (const unique_ptr_base &other) throw ()
      : m_ptr (const_cast<unique_ptr_base &> (other).release ()) {}
  
    /* Converting "move" constructor.  Really an lvalue ref converting
       constructor that actually moves.  This allows constructs such as:
  
        unique_ptr<Derived> func_returning_unique_ptr (.....);
        ...
        unique_ptr<Base> ptr = func_returning_unique_ptr (.....);
    */
    template<typename T1, typename D1>
    unique_ptr_base (const unique_ptr_base<T1, D1> &other) throw ()
      : m_ptr (const_cast<unique_ptr_base<T1, D1> &> (other).release ()) {}
  
    /* The "move" assignment operator.  Really an lvalue ref copy
       assignment operator that actually moves.  See comments above.  */
    unique_ptr_base &operator= (const unique_ptr_base &other) throw ()
    {
      reset (const_cast<unique_ptr_base &> (other).release ());
      return *this;
    }
  
    /* Converting "move" assignment.  Really an lvalue ref converting
       copy assignment operator that moves.  See comments above.  */
    template<typename T1, typename D1>
    unique_ptr_base &operator= (const unique_ptr_base<T1, D1> &other) throw ()
    {
      reset (const_cast<unique_ptr_base<T1, D1> &> (other).release ());
      return *this;
    }
  
    /* std::unique_ptr does not allow assignment, except from nullptr.
       nullptr doesn't exist in C++03, so we allow assignment from NULL
       instead [ptr = NULL;].
    */
    unique_ptr_base &operator= (detail::nullptr_t *) throw ()
    {
      reset ();
      return *this;
    }
  
    ~unique_ptr_base () { call_deleter (); }
  
    /* "explicit operator bool ()" emulation using the safe bool
       idiom.  */
  private:
    typedef void (unique_ptr_base::*explicit_operator_bool) () const;
    void this_type_does_not_support_comparisons () const {}
  
  public:
    operator explicit_operator_bool () const
    {
      return (m_ptr != NULL
  	    ? &unique_ptr_base::this_type_does_not_support_comparisons
  	    : 0);
    }
  
    element_type *get () const throw () { return m_ptr; }
  
    element_type *release () throw ()
    {
      pointer tmp = m_ptr;
      m_ptr = NULL;
      return tmp;
    }
  
    void reset (element_type *p = NULL) throw ()
    {
      if (p != m_ptr)
        {
  	call_deleter ();
  	m_ptr = p;
        }
    }
  
  private:
  
    /* Call the deleter.  Note we assume the deleter is "stateless".  */
    void call_deleter ()
    {
      D d;
  
      d (m_ptr);
    }
  
    element_type *m_ptr;
  };
  
  } /* namespace detail */
  
  /* Macro used to create a unique_ptr_base "partial specialization" --
     a subclass that uses a specific deleter.  Basically this re-defines
     the necessary constructors.  This is necessary because C++03
     doesn't support inheriting constructors with "using".  While at it,
     we inherit the assignment operator.  TYPE is the name of the type
     being defined.  Assumes that 'base_type' is a typedef of the
     baseclass TYPE is inheriting from.  */
  #define DEFINE_GNU_UNIQUE_PTR(TYPE)						\
  public:									\
    explicit TYPE (T *p = NULL) throw ()					\
      : base_type (p) {}							\
  									\
    TYPE (const TYPE &other) throw () : base_type (other) {}		\
  									\
    TYPE (detail::nullptr_t *) throw () : base_type (NULL) {}		\
  									\
    template<typename T1, typename D1>					\
    TYPE (const detail::unique_ptr_base<T1, D1> &other) throw ()		\
      : base_type (other) {}						\
  									\
    using base_type::operator=;
  
  /* Define single-object gnu::unique_ptr.  */
  
  template <typename T, typename D = default_delete<T> >
  class unique_ptr : public detail::unique_ptr_base<T, D>
  {
    typedef detail::unique_ptr_base<T, D> base_type;
  
    DEFINE_GNU_UNIQUE_PTR (unique_ptr)
  
  public:
    /* Dereferencing.  */
    T &operator* () const throw () { return *this->get (); }
    T *operator-> () const throw () { return this->get (); }
  };
  
  /* Define gnu::unique_ptr specialization for T[].  */
  
  template <typename T, typename D>
  class unique_ptr<T[], D> : public detail::unique_ptr_base<T, D>
  {
    typedef detail::unique_ptr_base<T, D> base_type;
  
    DEFINE_GNU_UNIQUE_PTR (unique_ptr)
  
  public:
    /* Indexing operator.  */
    T &operator[] (size_t i) const { return this->get ()[i]; }
  };
  
  /* Comparison operators.  */
  
  template <typename T, typename D,
  	  typename U, typename E>
  inline bool
  operator== (const detail::unique_ptr_base<T, D> &x,
  	    const detail::unique_ptr_base<U, E> &y)
  { return x.get() == y.get(); }
  
  template <typename T, typename D,
  	  typename U, typename E>
  inline bool
  operator!= (const detail::unique_ptr_base<T, D> &x,
  	    const detail::unique_ptr_base<U, E> &y)
  { return x.get() != y.get(); }
  
  template<typename T, typename D,
  	 typename U, typename E>
  inline bool
  operator< (const detail::unique_ptr_base<T, D> &x,
  	   const detail::unique_ptr_base<U, E> &y)
  { return x.get() < y.get (); }
  
  template<typename T, typename D,
  	 typename U, typename E>
  inline bool
  operator<= (const detail::unique_ptr_base<T, D> &x,
  	    const detail::unique_ptr_base<U, E> &y)
  { return !(y < x); }
  
  template<typename T, typename D,
  	 typename U, typename E>
  inline bool
  operator> (const detail::unique_ptr_base<T, D> &x,
  	   const detail::unique_ptr_base<U, E> &y)
  { return y < x; }
  
  template<typename T, typename D,
  	 typename U, typename E>
  inline bool
  operator>= (const detail::unique_ptr_base<T, D> &x,
  	    const detail::unique_ptr_base<U, E> &y)
  { return !(x < y); }
  
  /* std::move "emulation".  This is as simple as it can be -- no
     attempt is made to emulate rvalue references.  This relies on T
     having move semantics like std::auto_ptr.
     I.e., copy/assignment actually moves.  */
  
  template<typename T>
  const T&
  move (T& v)
  {
    return v;
  }
  
  #endif /* C++11 */
  
  /* Define gnu::unique_xmalloc_ptr, a gnu::unique_ptr that manages
     xmalloc'ed memory.  */
  
  /* The deleter for gnu::unique_xmalloc_ptr.  Uses free.  */
  template <typename T>
  struct xmalloc_deleter
  {
    void operator() (T *ptr) const { free (ptr); }
  };
  
  /* Same, for arrays.  */
  template <typename T>
  struct xmalloc_deleter<T[]>
  {
    void operator() (T *ptr) const { free (ptr); }
  };
  
  #if __cplusplus >= 201103
  
  /* In C++11, we just import the standard unique_ptr to our namespace
     with a custom deleter.  */
  
  template<typename T> using unique_xmalloc_ptr
    = std::unique_ptr<T, xmalloc_deleter<T>>;
  
  #else /* C++11 */
  
  /* In C++03, we don't have template aliases, so we need to define a
     subclass instead, and re-define the constructors, because C++03
     doesn't support inheriting constructors either.  */
  
  template <typename T>
  class unique_xmalloc_ptr : public unique_ptr<T, xmalloc_deleter<T> >
  {
    typedef unique_ptr<T, xmalloc_deleter<T> > base_type;
  
    DEFINE_GNU_UNIQUE_PTR (unique_xmalloc_ptr)
  };
  
  /* Define gnu::unique_xmalloc_ptr specialization for T[].  */
  
  template <typename T>
  class unique_xmalloc_ptr<T[]> : public unique_ptr<T[], xmalloc_deleter<T[]> >
  {
    typedef unique_ptr<T[], xmalloc_deleter<T[]> > base_type;
  
    DEFINE_GNU_UNIQUE_PTR (unique_xmalloc_ptr)
  };
  
  #endif /* C++11 */
  
  } /* namespace gnu */
  
  #endif /* GNU_UNIQUE_PTR_H */
  