// Custom pointer adapter and sample storage policies

// Copyright (C) 2008-2019 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
// any later version.

// This library 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.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/**
 *  @file ext/pointer.h
 *  This file is a GNU extension to the Standard C++ Library.
 *
 *  @author Bob Walters
 *
 * Provides reusable _Pointer_adapter for assisting in the development of
 * custom pointer types that can be used with the standard containers via
 * the allocator::pointer and allocator::const_pointer typedefs.
 */

#ifndef _POINTER_H
#define _POINTER_H 1

#pragma GCC system_header

#include <iosfwd>
#include <bits/stl_iterator_base_types.h>
#include <ext/cast.h>
#include <ext/type_traits.h>
#if __cplusplus >= 201103L
# include <bits/move.h>
# include <bits/ptr_traits.h>
#endif

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /** 
   * @brief A storage policy for use with _Pointer_adapter<> which yields a
   *        standard pointer.
   * 
   *  A _Storage_policy is required to provide 4 things:
   *    1) A get() API for returning the stored pointer value.
   *    2) An set() API for storing a pointer value.
   *    3) An element_type typedef to define the type this points to.
   *    4) An operator<() to support pointer comparison.
   *    5) An operator==() to support pointer comparison.
   */
  template<typename _Tp> 
    class _Std_pointer_impl 
    {
    public:
      // the type this pointer points to.
      typedef _Tp element_type;
  
      // A method to fetch the pointer value as a standard T* value;
      inline _Tp* 
      get() const 
      { return _M_value; }
  
      // A method to set the pointer value, from a standard T* value;
      inline void 
      set(element_type* __arg) 
      { _M_value = __arg; }
  
      // Comparison of pointers
      inline bool
      operator<(const _Std_pointer_impl& __rarg) const
      { return (_M_value < __rarg._M_value); }
  
      inline bool
      operator==(const _Std_pointer_impl& __rarg) const
      { return (_M_value == __rarg._M_value); }

    private:
      element_type* _M_value;
    };

  /**
   * @brief A storage policy for use with _Pointer_adapter<> which stores
   *        the pointer's address as an offset value which is relative to
   *        its own address.
   * 
   * This is intended for pointers within shared memory regions which
   * might be mapped at different addresses by different processes.
   * For null pointers, a value of 1 is used.  (0 is legitimate
   * sometimes for nodes in circularly linked lists) This value was
   * chosen as the least likely to generate an incorrect null, As
   * there is no reason why any normal pointer would point 1 byte into
   * its own pointer address.
   */
  template<typename _Tp> 
    class _Relative_pointer_impl 
    {
    public:
      typedef _Tp element_type;
  
      _Tp*
      get() const 
      {
        if (_M_diff == 1)
          return 0;
        else
          return reinterpret_cast<_Tp*>(reinterpret_cast<_UIntPtrType>(this)
					+ _M_diff);
      }
  
      void 
      set(_Tp* __arg)
      {
        if (!__arg)
          _M_diff = 1;
        else
          _M_diff = reinterpret_cast<_UIntPtrType>(__arg) 
                    - reinterpret_cast<_UIntPtrType>(this);
      }
  
      // Comparison of pointers
      inline bool
      operator<(const _Relative_pointer_impl& __rarg) const
      { return (reinterpret_cast<_UIntPtrType>(this->get())
		< reinterpret_cast<_UIntPtrType>(__rarg.get())); }

      inline bool
      operator==(const _Relative_pointer_impl& __rarg) const
      { return (reinterpret_cast<_UIntPtrType>(this->get())
		== reinterpret_cast<_UIntPtrType>(__rarg.get())); }

    private:
#ifdef _GLIBCXX_USE_LONG_LONG
      typedef __gnu_cxx::__conditional_type<
	 (sizeof(unsigned long) >= sizeof(void*)),
	 unsigned long, unsigned long long>::__type _UIntPtrType;
#else
      typedef unsigned long _UIntPtrType;
#endif
      _UIntPtrType _M_diff;
    };
  
  /**
   * Relative_pointer_impl needs a specialization for const T because of
   * the casting done during pointer arithmetic.
   */
  template<typename _Tp> 
    class _Relative_pointer_impl<const _Tp> 
    {
    public:
      typedef const _Tp element_type;
  
      const _Tp*
      get() const
      {
        if (_M_diff == 1)
          return 0;
        else
          return reinterpret_cast<const _Tp*>
	      (reinterpret_cast<_UIntPtrType>(this) + _M_diff);
      }
  
      void 
      set(const _Tp* __arg)
      {
        if (!__arg)
          _M_diff = 1;
        else
          _M_diff = reinterpret_cast<_UIntPtrType>(__arg) 
                    - reinterpret_cast<_UIntPtrType>(this);
      }
  
      // Comparison of pointers
      inline bool
      operator<(const _Relative_pointer_impl& __rarg) const
      { return (reinterpret_cast<_UIntPtrType>(this->get())
		< reinterpret_cast<_UIntPtrType>(__rarg.get())); }

      inline bool
      operator==(const _Relative_pointer_impl& __rarg) const
      { return (reinterpret_cast<_UIntPtrType>(this->get())
		== reinterpret_cast<_UIntPtrType>(__rarg.get())); }
  
    private:
#ifdef _GLIBCXX_USE_LONG_LONG
      typedef __gnu_cxx::__conditional_type<
	 (sizeof(unsigned long) >= sizeof(void*)),
	 unsigned long, unsigned long long>::__type _UIntPtrType;
#else
      typedef unsigned long _UIntPtrType;
#endif
       _UIntPtrType _M_diff;
    };

  /**
   * The specialization on this type helps resolve the problem of
   * reference to void, and eliminates the need to specialize
   * _Pointer_adapter for cases of void*, const void*, and so on.
   */
  struct _Invalid_type { };
  
  template<typename _Tp>
    struct _Reference_type 
    { typedef _Tp& reference; };

  template<> 
    struct _Reference_type<void> 
    { typedef _Invalid_type& reference; };

  template<> 
    struct _Reference_type<const void> 
    { typedef const _Invalid_type& reference; };

  template<> 
    struct _Reference_type<volatile void> 
    { typedef volatile _Invalid_type&  reference; };

  template<> 
    struct _Reference_type<volatile const void> 
    { typedef const volatile _Invalid_type&  reference; };

  /**
   * This structure accommodates the way in which
   * std::iterator_traits<> is normally specialized for const T*, so
   * that value_type is still T.
   */
  template<typename _Tp> 
    struct _Unqualified_type 
    { typedef _Tp type; };
    
  template<typename _Tp> 
    struct _Unqualified_type<const _Tp> 
    { typedef _Tp type; };
    
  /**
   * The following provides an 'alternative pointer' that works with
   * the containers when specified as the pointer typedef of the
   * allocator.
   *
   * The pointer type used with the containers doesn't have to be this
   * class, but it must support the implicit conversions, pointer
   * arithmetic, comparison operators, etc. that are supported by this
   * class, and avoid raising compile-time ambiguities.  Because
   * creating a working pointer can be challenging, this pointer
   * template was designed to wrapper an easier storage policy type,
   * so that it becomes reusable for creating other pointer types.
   *
   * A key point of this class is also that it allows container
   * writers to 'assume' Allocator::pointer is a typedef for a normal
   * pointer.  This class supports most of the conventions of a true
   * pointer, and can, for instance handle implicit conversion to
   * const and base class pointer types.  The only impositions on
   * container writers to support extended pointers are: 1) use the
   * Allocator::pointer typedef appropriately for pointer types.  2)
   * if you need pointer casting, use the __pointer_cast<> functions
   * from ext/cast.h.  This allows pointer cast operations to be
   * overloaded as necessary by custom pointers.
   *
   * Note: The const qualifier works with this pointer adapter as
   * follows:
   *
   * _Tp*             == _Pointer_adapter<_Std_pointer_impl<_Tp> >;
   * const _Tp*       == _Pointer_adapter<_Std_pointer_impl<const _Tp> >;
   * _Tp* const       == const _Pointer_adapter<_Std_pointer_impl<_Tp> >;
   * const _Tp* const == const _Pointer_adapter<_Std_pointer_impl<const _Tp> >;
   */
  template<typename _Storage_policy>
    class _Pointer_adapter : public _Storage_policy 
    {
    public:
      typedef typename _Storage_policy::element_type element_type;

      // These are needed for iterator_traits
      typedef std::random_access_iterator_tag                iterator_category;
      typedef typename _Unqualified_type<element_type>::type value_type;
      typedef std::ptrdiff_t                                 difference_type;
      typedef _Pointer_adapter                               pointer;
      typedef typename _Reference_type<element_type>::reference  reference;

      // Reminder: 'const' methods mean that the method is valid when the 
      // pointer is immutable, and has nothing to do with whether the 
      // 'pointee' is const.

      // Default Constructor (Convert from element_type*)
      _Pointer_adapter(element_type* __arg = 0)
      { _Storage_policy::set(__arg); }

      // Copy constructor from _Pointer_adapter of same type.
      _Pointer_adapter(const _Pointer_adapter& __arg) 
      { _Storage_policy::set(__arg.get()); }

      // Convert from _Up* if conversion to element_type* is valid.
      template<typename _Up>
        _Pointer_adapter(_Up* __arg)
        { _Storage_policy::set(__arg); }

      // Conversion from another _Pointer_adapter if _Up if static cast is
      // valid.
      template<typename _Up>
        _Pointer_adapter(const _Pointer_adapter<_Up>& __arg)
        { _Storage_policy::set(__arg.get()); }

      // Destructor
      ~_Pointer_adapter() { }
  
      // Assignment operator
      _Pointer_adapter&
      operator=(const _Pointer_adapter& __arg) 
      {
        _Storage_policy::set(__arg.get()); 
        return *this; 
      }

      template<typename _Up>
        _Pointer_adapter&
        operator=(const _Pointer_adapter<_Up>& __arg)
        {
          _Storage_policy::set(__arg.get()); 
          return *this; 
        }

      template<typename _Up>
        _Pointer_adapter&
        operator=(_Up* __arg)
        {
          _Storage_policy::set(__arg); 
          return *this; 
        }

      // Operator*, returns element_type&
      inline reference 
      operator*() const 
      { return *(_Storage_policy::get()); }

      // Operator->, returns element_type*
      inline element_type* 
      operator->() const 
      { return _Storage_policy::get(); }

      // Operator[], returns a element_type& to the item at that loc.
      inline reference
      operator[](std::ptrdiff_t __index) const
      { return _Storage_policy::get()[__index]; }

      // To allow implicit conversion to "bool", for "if (ptr)..."
#if __cplusplus >= 201103L
      explicit operator bool() const { return _Storage_policy::get() != 0; }
#else
    private:
      typedef element_type*(_Pointer_adapter::*__unspecified_bool_type)() const;

    public:
      operator __unspecified_bool_type() const
      {
        return _Storage_policy::get() == 0 ? 0 : 
                         &_Pointer_adapter::operator->; 
      }

      // ! operator (for: if (!ptr)...)
      inline bool
      operator!() const 
      { return (_Storage_policy::get() == 0); }
#endif
  
      // Pointer differences
      inline friend std::ptrdiff_t 
      operator-(const _Pointer_adapter& __lhs, element_type* __rhs) 
      { return (__lhs.get() - __rhs); }
  
      inline friend std::ptrdiff_t 
      operator-(element_type* __lhs, const _Pointer_adapter& __rhs) 
      { return (__lhs - __rhs.get()); }
  
      template<typename _Up>
        inline friend std::ptrdiff_t 
        operator-(const _Pointer_adapter& __lhs, _Up* __rhs) 
        { return (__lhs.get() - __rhs); }
    
      template<typename _Up>
        inline friend std::ptrdiff_t 
        operator-(_Up* __lhs, const _Pointer_adapter& __rhs)
        { return (__lhs - __rhs.get()); }

      template<typename _Up>
        inline std::ptrdiff_t 
        operator-(const _Pointer_adapter<_Up>& __rhs) const 
        { return (_Storage_policy::get() - __rhs.get()); }
  
      // Pointer math
      // Note: There is a reason for all this overloading based on different
      // integer types.  In some libstdc++-v3 test cases, a templated
      // operator+ is declared which can match any types.  This operator
      // tends to "steal" the recognition of _Pointer_adapter's own operator+ 
      // unless the integer type matches perfectly.

#define _CXX_POINTER_ARITH_OPERATOR_SET(INT_TYPE) \
      inline friend _Pointer_adapter \
      operator+(const _Pointer_adapter& __lhs, INT_TYPE __offset) \
      { return _Pointer_adapter(__lhs.get() + __offset); } \
\
      inline friend _Pointer_adapter \
      operator+(INT_TYPE __offset, const _Pointer_adapter& __rhs) \
      { return _Pointer_adapter(__rhs.get() + __offset); } \
\
      inline friend _Pointer_adapter \
      operator-(const _Pointer_adapter& __lhs, INT_TYPE __offset) \
      { return _Pointer_adapter(__lhs.get() - __offset); } \
\
      inline _Pointer_adapter& \
      operator+=(INT_TYPE __offset) \
      { \
        _Storage_policy::set(_Storage_policy::get() + __offset); \
        return *this; \
      } \
\
      inline _Pointer_adapter& \
      operator-=(INT_TYPE __offset) \
      { \
        _Storage_policy::set(_Storage_policy::get() - __offset); \
        return *this; \
      } \
// END of _CXX_POINTER_ARITH_OPERATOR_SET macro
  
      // Expand into the various pointer arithmetic operators needed.
      _CXX_POINTER_ARITH_OPERATOR_SET(short);
      _CXX_POINTER_ARITH_OPERATOR_SET(unsigned short);
      _CXX_POINTER_ARITH_OPERATOR_SET(int);
      _CXX_POINTER_ARITH_OPERATOR_SET(unsigned int);
      _CXX_POINTER_ARITH_OPERATOR_SET(long);
      _CXX_POINTER_ARITH_OPERATOR_SET(unsigned long);
#ifdef _GLIBCXX_USE_LONG_LONG
      _CXX_POINTER_ARITH_OPERATOR_SET(long long);
      _CXX_POINTER_ARITH_OPERATOR_SET(unsigned long long);
#endif

      // Mathematical Manipulators
      inline _Pointer_adapter& 
      operator++()
      {
        _Storage_policy::set(_Storage_policy::get() + 1); 
        return *this;
      }
  
      inline _Pointer_adapter 
      operator++(int)
      {
        _Pointer_adapter __tmp(*this);
        _Storage_policy::set(_Storage_policy::get() + 1);
        return __tmp;
      }
  
      inline _Pointer_adapter& 
      operator--() 
      {
        _Storage_policy::set(_Storage_policy::get() - 1); 
        return *this;
      }
  
      inline _Pointer_adapter
      operator--(int) 
      {
        _Pointer_adapter __tmp(*this);
        _Storage_policy::set(_Storage_policy::get() - 1);
        return __tmp;
      }
  
    }; // class _Pointer_adapter


#define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(OPERATOR) \
  template<typename _Tp1, typename _Tp2> \
    inline bool \
    operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, _Tp2 __rhs) \
    { return __lhs.get() OPERATOR __rhs; } \
\
  template<typename _Tp1, typename _Tp2> \
    inline bool \
    operator OPERATOR(_Tp1 __lhs, const _Pointer_adapter<_Tp2>& __rhs) \
    { return __lhs OPERATOR __rhs.get(); } \
\
  template<typename _Tp1, typename _Tp2> \
    inline bool \
    operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, \
                              const _Pointer_adapter<_Tp2>& __rhs) \
    { return __lhs.get() OPERATOR __rhs.get(); } \
\
// End GCC_CXX_POINTER_COMPARISON_OPERATION_SET Macro
  
  // Expand into the various comparison operators needed.
  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(==)
  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(!=)
  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<)
  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<=)
  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>)
  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>=)

  // These are here for expressions like "ptr == 0", "ptr != 0"
  template<typename _Tp>
    inline bool
    operator==(const _Pointer_adapter<_Tp>& __lhs, int __rhs)
    { return __lhs.get() == reinterpret_cast<void*>(__rhs); } 

  template<typename _Tp>
    inline bool
    operator==(int __lhs, const _Pointer_adapter<_Tp>& __rhs)
    { return __rhs.get() == reinterpret_cast<void*>(__lhs); } 

  template<typename _Tp>
    inline bool
    operator!=(const _Pointer_adapter<_Tp>& __lhs, int __rhs)
    { return __lhs.get() != reinterpret_cast<void*>(__rhs); } 

  template<typename _Tp>
    inline bool
    operator!=(int __lhs, const _Pointer_adapter<_Tp>& __rhs)
    { return __rhs.get() != reinterpret_cast<void*>(__lhs); } 

  /**
   * Comparison operators for _Pointer_adapter defer to the base class'
   * comparison operators, when possible.
   */
  template<typename _Tp>
    inline bool
    operator==(const _Pointer_adapter<_Tp>& __lhs, 
               const _Pointer_adapter<_Tp>& __rhs)
    { return __lhs._Tp::operator==(__rhs); }

  template<typename _Tp>
    inline bool
    operator<=(const _Pointer_adapter<_Tp>& __lhs, 
               const _Pointer_adapter<_Tp>& __rhs)
    { return __lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs); }

  template<typename _Tp>
    inline bool
    operator!=(const _Pointer_adapter<_Tp>& __lhs, 
               const _Pointer_adapter<_Tp>& __rhs)
    { return !(__lhs._Tp::operator==(__rhs)); }

  template<typename _Tp>
    inline bool
    operator>(const _Pointer_adapter<_Tp>& __lhs, 
              const _Pointer_adapter<_Tp>& __rhs)
    { return !(__lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs)); }

  template<typename _Tp>
    inline bool
    operator>=(const _Pointer_adapter<_Tp>& __lhs, 
               const _Pointer_adapter<_Tp>& __rhs)
    { return !(__lhs._Tp::operator<(__rhs)); }

  template<typename _CharT, typename _Traits, typename _StoreT>
    inline std::basic_ostream<_CharT, _Traits>&
    operator<<(std::basic_ostream<_CharT, _Traits>& __os, 
               const _Pointer_adapter<_StoreT>& __p)
    { return (__os << __p.get()); }

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#if __cplusplus >= 201103L
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  template<typename _Storage_policy>
    struct pointer_traits<__gnu_cxx::_Pointer_adapter<_Storage_policy>>
    {
      /// The pointer type
      typedef __gnu_cxx::_Pointer_adapter<_Storage_policy>         pointer;
      /// The type pointed to
      typedef typename pointer::element_type            element_type;
      /// Type used to represent the difference between two pointers
      typedef typename pointer::difference_type         difference_type;

      template<typename _Up>
        using rebind = typename __gnu_cxx::_Pointer_adapter<
	typename pointer_traits<_Storage_policy>::template rebind<_Up>>;

      static pointer pointer_to(typename pointer::reference __r) noexcept
      { return pointer(std::addressof(__r)); }
    };

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

#endif // _POINTER_H
