// Custom pointer adapter and sample storage policies

// Copyright (C) 2008, 2009, 2010 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>

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 accomodates 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; };
    
  template<typename _Tp> 
    struct _Unqualified_type<volatile _Tp> 
    { typedef volatile _Tp type; };
    
  template<typename _Tp> 
    struct _Unqualified_type<volatile const _Tp> 
    { typedef volatile _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' Alocator::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 is 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)..."
    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); }
  
      // 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 arithmatic 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);

      // 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'es
   * 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

#endif // _POINTER_H
