xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/ext/pointer.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
136ac495dSmrg // Custom pointer adapter and sample storage policies
236ac495dSmrg 
3*8feb0f0bSmrg // Copyright (C) 2008-2020 Free Software Foundation, Inc.
436ac495dSmrg //
536ac495dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
636ac495dSmrg // software; you can redistribute it and/or modify it under the
736ac495dSmrg // terms of the GNU General Public License as published by the
836ac495dSmrg // Free Software Foundation; either version 3, or (at your option)
936ac495dSmrg // any later version.
1036ac495dSmrg 
1136ac495dSmrg // This library is distributed in the hope that it will be useful,
1236ac495dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
1336ac495dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1436ac495dSmrg // GNU General Public License for more details.
1536ac495dSmrg 
1636ac495dSmrg // Under Section 7 of GPL version 3, you are granted additional
1736ac495dSmrg // permissions described in the GCC Runtime Library Exception, version
1836ac495dSmrg // 3.1, as published by the Free Software Foundation.
1936ac495dSmrg 
2036ac495dSmrg // You should have received a copy of the GNU General Public License and
2136ac495dSmrg // a copy of the GCC Runtime Library Exception along with this program;
2236ac495dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2336ac495dSmrg // <http://www.gnu.org/licenses/>.
2436ac495dSmrg 
2536ac495dSmrg /**
2636ac495dSmrg  *  @file ext/pointer.h
2736ac495dSmrg  *  This file is a GNU extension to the Standard C++ Library.
2836ac495dSmrg  *
2936ac495dSmrg  *  @author Bob Walters
3036ac495dSmrg  *
3136ac495dSmrg  * Provides reusable _Pointer_adapter for assisting in the development of
3236ac495dSmrg  * custom pointer types that can be used with the standard containers via
3336ac495dSmrg  * the allocator::pointer and allocator::const_pointer typedefs.
3436ac495dSmrg  */
3536ac495dSmrg 
3636ac495dSmrg #ifndef _POINTER_H
3736ac495dSmrg #define _POINTER_H 1
3836ac495dSmrg 
3936ac495dSmrg #pragma GCC system_header
4036ac495dSmrg 
4136ac495dSmrg #include <iosfwd>
4236ac495dSmrg #include <bits/stl_iterator_base_types.h>
4336ac495dSmrg #include <ext/cast.h>
4436ac495dSmrg #include <ext/type_traits.h>
4536ac495dSmrg #if __cplusplus >= 201103L
4636ac495dSmrg # include <bits/move.h>
4736ac495dSmrg # include <bits/ptr_traits.h>
4836ac495dSmrg #endif
49*8feb0f0bSmrg #if __cplusplus > 201703L
50*8feb0f0bSmrg # include <iterator> // for indirectly_readable_traits
51*8feb0f0bSmrg #endif
5236ac495dSmrg 
_GLIBCXX_VISIBILITY(default)5336ac495dSmrg namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
5436ac495dSmrg {
5536ac495dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
5636ac495dSmrg 
5736ac495dSmrg   /**
5836ac495dSmrg    * @brief A storage policy for use with _Pointer_adapter<> which yields a
5936ac495dSmrg    *        standard pointer.
6036ac495dSmrg    *
6136ac495dSmrg    *  A _Storage_policy is required to provide 4 things:
6236ac495dSmrg    *    1) A get() API for returning the stored pointer value.
6336ac495dSmrg    *    2) An set() API for storing a pointer value.
6436ac495dSmrg    *    3) An element_type typedef to define the type this points to.
6536ac495dSmrg    *    4) An operator<() to support pointer comparison.
6636ac495dSmrg    *    5) An operator==() to support pointer comparison.
6736ac495dSmrg    */
6836ac495dSmrg   template<typename _Tp>
6936ac495dSmrg     class _Std_pointer_impl
7036ac495dSmrg     {
7136ac495dSmrg     public:
7236ac495dSmrg       // the type this pointer points to.
7336ac495dSmrg       typedef _Tp element_type;
7436ac495dSmrg 
7536ac495dSmrg       // A method to fetch the pointer value as a standard T* value;
7636ac495dSmrg       inline _Tp*
7736ac495dSmrg       get() const
7836ac495dSmrg       { return _M_value; }
7936ac495dSmrg 
8036ac495dSmrg       // A method to set the pointer value, from a standard T* value;
8136ac495dSmrg       inline void
8236ac495dSmrg       set(element_type* __arg)
8336ac495dSmrg       { _M_value = __arg; }
8436ac495dSmrg 
8536ac495dSmrg       // Comparison of pointers
8636ac495dSmrg       inline bool
8736ac495dSmrg       operator<(const _Std_pointer_impl& __rarg) const
8836ac495dSmrg       { return (_M_value < __rarg._M_value); }
8936ac495dSmrg 
9036ac495dSmrg       inline bool
9136ac495dSmrg       operator==(const _Std_pointer_impl& __rarg) const
9236ac495dSmrg       { return (_M_value == __rarg._M_value); }
9336ac495dSmrg 
9436ac495dSmrg     private:
9536ac495dSmrg       element_type* _M_value;
9636ac495dSmrg     };
9736ac495dSmrg 
9836ac495dSmrg   /**
9936ac495dSmrg    * @brief A storage policy for use with _Pointer_adapter<> which stores
10036ac495dSmrg    *        the pointer's address as an offset value which is relative to
10136ac495dSmrg    *        its own address.
10236ac495dSmrg    *
10336ac495dSmrg    * This is intended for pointers within shared memory regions which
10436ac495dSmrg    * might be mapped at different addresses by different processes.
10536ac495dSmrg    * For null pointers, a value of 1 is used.  (0 is legitimate
10636ac495dSmrg    * sometimes for nodes in circularly linked lists) This value was
10736ac495dSmrg    * chosen as the least likely to generate an incorrect null, As
10836ac495dSmrg    * there is no reason why any normal pointer would point 1 byte into
10936ac495dSmrg    * its own pointer address.
11036ac495dSmrg    */
11136ac495dSmrg   template<typename _Tp>
11236ac495dSmrg     class _Relative_pointer_impl
11336ac495dSmrg     {
11436ac495dSmrg     public:
11536ac495dSmrg       typedef _Tp element_type;
11636ac495dSmrg 
11736ac495dSmrg       _Tp*
11836ac495dSmrg       get() const
11936ac495dSmrg       {
12036ac495dSmrg         if (_M_diff == 1)
12136ac495dSmrg           return 0;
12236ac495dSmrg         else
12336ac495dSmrg           return reinterpret_cast<_Tp*>(reinterpret_cast<_UIntPtrType>(this)
12436ac495dSmrg 					+ _M_diff);
12536ac495dSmrg       }
12636ac495dSmrg 
12736ac495dSmrg       void
12836ac495dSmrg       set(_Tp* __arg)
12936ac495dSmrg       {
13036ac495dSmrg         if (!__arg)
13136ac495dSmrg           _M_diff = 1;
13236ac495dSmrg         else
13336ac495dSmrg           _M_diff = reinterpret_cast<_UIntPtrType>(__arg)
13436ac495dSmrg                     - reinterpret_cast<_UIntPtrType>(this);
13536ac495dSmrg       }
13636ac495dSmrg 
13736ac495dSmrg       // Comparison of pointers
13836ac495dSmrg       inline bool
13936ac495dSmrg       operator<(const _Relative_pointer_impl& __rarg) const
14036ac495dSmrg       { return (reinterpret_cast<_UIntPtrType>(this->get())
14136ac495dSmrg 		< reinterpret_cast<_UIntPtrType>(__rarg.get())); }
14236ac495dSmrg 
14336ac495dSmrg       inline bool
14436ac495dSmrg       operator==(const _Relative_pointer_impl& __rarg) const
14536ac495dSmrg       { return (reinterpret_cast<_UIntPtrType>(this->get())
14636ac495dSmrg 		== reinterpret_cast<_UIntPtrType>(__rarg.get())); }
14736ac495dSmrg 
14836ac495dSmrg     private:
14936ac495dSmrg #ifdef _GLIBCXX_USE_LONG_LONG
15036ac495dSmrg       typedef __gnu_cxx::__conditional_type<
15136ac495dSmrg 	 (sizeof(unsigned long) >= sizeof(void*)),
15236ac495dSmrg 	 unsigned long, unsigned long long>::__type _UIntPtrType;
15336ac495dSmrg #else
15436ac495dSmrg       typedef unsigned long _UIntPtrType;
15536ac495dSmrg #endif
15636ac495dSmrg       _UIntPtrType _M_diff;
15736ac495dSmrg     };
15836ac495dSmrg 
15936ac495dSmrg   /**
16036ac495dSmrg    * Relative_pointer_impl needs a specialization for const T because of
16136ac495dSmrg    * the casting done during pointer arithmetic.
16236ac495dSmrg    */
16336ac495dSmrg   template<typename _Tp>
16436ac495dSmrg     class _Relative_pointer_impl<const _Tp>
16536ac495dSmrg     {
16636ac495dSmrg     public:
16736ac495dSmrg       typedef const _Tp element_type;
16836ac495dSmrg 
16936ac495dSmrg       const _Tp*
17036ac495dSmrg       get() const
17136ac495dSmrg       {
17236ac495dSmrg         if (_M_diff == 1)
17336ac495dSmrg           return 0;
17436ac495dSmrg         else
17536ac495dSmrg           return reinterpret_cast<const _Tp*>
17636ac495dSmrg 	      (reinterpret_cast<_UIntPtrType>(this) + _M_diff);
17736ac495dSmrg       }
17836ac495dSmrg 
17936ac495dSmrg       void
18036ac495dSmrg       set(const _Tp* __arg)
18136ac495dSmrg       {
18236ac495dSmrg         if (!__arg)
18336ac495dSmrg           _M_diff = 1;
18436ac495dSmrg         else
18536ac495dSmrg           _M_diff = reinterpret_cast<_UIntPtrType>(__arg)
18636ac495dSmrg                     - reinterpret_cast<_UIntPtrType>(this);
18736ac495dSmrg       }
18836ac495dSmrg 
18936ac495dSmrg       // Comparison of pointers
19036ac495dSmrg       inline bool
19136ac495dSmrg       operator<(const _Relative_pointer_impl& __rarg) const
19236ac495dSmrg       { return (reinterpret_cast<_UIntPtrType>(this->get())
19336ac495dSmrg 		< reinterpret_cast<_UIntPtrType>(__rarg.get())); }
19436ac495dSmrg 
19536ac495dSmrg       inline bool
19636ac495dSmrg       operator==(const _Relative_pointer_impl& __rarg) const
19736ac495dSmrg       { return (reinterpret_cast<_UIntPtrType>(this->get())
19836ac495dSmrg 		== reinterpret_cast<_UIntPtrType>(__rarg.get())); }
19936ac495dSmrg 
20036ac495dSmrg     private:
20136ac495dSmrg #ifdef _GLIBCXX_USE_LONG_LONG
20236ac495dSmrg       typedef __gnu_cxx::__conditional_type<
20336ac495dSmrg 	 (sizeof(unsigned long) >= sizeof(void*)),
20436ac495dSmrg 	 unsigned long, unsigned long long>::__type _UIntPtrType;
20536ac495dSmrg #else
20636ac495dSmrg       typedef unsigned long _UIntPtrType;
20736ac495dSmrg #endif
20836ac495dSmrg        _UIntPtrType _M_diff;
20936ac495dSmrg     };
21036ac495dSmrg 
21136ac495dSmrg   /**
21236ac495dSmrg    * The specialization on this type helps resolve the problem of
21336ac495dSmrg    * reference to void, and eliminates the need to specialize
21436ac495dSmrg    * _Pointer_adapter for cases of void*, const void*, and so on.
21536ac495dSmrg    */
21636ac495dSmrg   struct _Invalid_type { };
21736ac495dSmrg 
21836ac495dSmrg   template<typename _Tp>
21936ac495dSmrg     struct _Reference_type
22036ac495dSmrg     { typedef _Tp& reference; };
22136ac495dSmrg 
22236ac495dSmrg   template<>
22336ac495dSmrg     struct _Reference_type<void>
22436ac495dSmrg     { typedef _Invalid_type& reference; };
22536ac495dSmrg 
22636ac495dSmrg   template<>
22736ac495dSmrg     struct _Reference_type<const void>
22836ac495dSmrg     { typedef const _Invalid_type& reference; };
22936ac495dSmrg 
23036ac495dSmrg   template<>
23136ac495dSmrg     struct _Reference_type<volatile void>
23236ac495dSmrg     { typedef volatile _Invalid_type&  reference; };
23336ac495dSmrg 
23436ac495dSmrg   template<>
23536ac495dSmrg     struct _Reference_type<volatile const void>
23636ac495dSmrg     { typedef const volatile _Invalid_type&  reference; };
23736ac495dSmrg 
23836ac495dSmrg   /**
23936ac495dSmrg    * This structure accommodates the way in which
24036ac495dSmrg    * std::iterator_traits<> is normally specialized for const T*, so
24136ac495dSmrg    * that value_type is still T.
24236ac495dSmrg    */
24336ac495dSmrg   template<typename _Tp>
24436ac495dSmrg     struct _Unqualified_type
24536ac495dSmrg     { typedef _Tp type; };
24636ac495dSmrg 
24736ac495dSmrg   template<typename _Tp>
24836ac495dSmrg     struct _Unqualified_type<const _Tp>
24936ac495dSmrg     { typedef _Tp type; };
25036ac495dSmrg 
25136ac495dSmrg   /**
25236ac495dSmrg    * The following provides an 'alternative pointer' that works with
25336ac495dSmrg    * the containers when specified as the pointer typedef of the
25436ac495dSmrg    * allocator.
25536ac495dSmrg    *
25636ac495dSmrg    * The pointer type used with the containers doesn't have to be this
25736ac495dSmrg    * class, but it must support the implicit conversions, pointer
25836ac495dSmrg    * arithmetic, comparison operators, etc. that are supported by this
25936ac495dSmrg    * class, and avoid raising compile-time ambiguities.  Because
26036ac495dSmrg    * creating a working pointer can be challenging, this pointer
26136ac495dSmrg    * template was designed to wrapper an easier storage policy type,
26236ac495dSmrg    * so that it becomes reusable for creating other pointer types.
26336ac495dSmrg    *
26436ac495dSmrg    * A key point of this class is also that it allows container
26536ac495dSmrg    * writers to 'assume' Allocator::pointer is a typedef for a normal
26636ac495dSmrg    * pointer.  This class supports most of the conventions of a true
26736ac495dSmrg    * pointer, and can, for instance handle implicit conversion to
26836ac495dSmrg    * const and base class pointer types.  The only impositions on
26936ac495dSmrg    * container writers to support extended pointers are: 1) use the
27036ac495dSmrg    * Allocator::pointer typedef appropriately for pointer types.  2)
27136ac495dSmrg    * if you need pointer casting, use the __pointer_cast<> functions
27236ac495dSmrg    * from ext/cast.h.  This allows pointer cast operations to be
27336ac495dSmrg    * overloaded as necessary by custom pointers.
27436ac495dSmrg    *
27536ac495dSmrg    * Note: The const qualifier works with this pointer adapter as
27636ac495dSmrg    * follows:
27736ac495dSmrg    *
27836ac495dSmrg    * _Tp*             == _Pointer_adapter<_Std_pointer_impl<_Tp> >;
27936ac495dSmrg    * const _Tp*       == _Pointer_adapter<_Std_pointer_impl<const _Tp> >;
28036ac495dSmrg    * _Tp* const       == const _Pointer_adapter<_Std_pointer_impl<_Tp> >;
28136ac495dSmrg    * const _Tp* const == const _Pointer_adapter<_Std_pointer_impl<const _Tp> >;
28236ac495dSmrg    */
28336ac495dSmrg   template<typename _Storage_policy>
28436ac495dSmrg     class _Pointer_adapter : public _Storage_policy
28536ac495dSmrg     {
28636ac495dSmrg     public:
28736ac495dSmrg       typedef typename _Storage_policy::element_type element_type;
28836ac495dSmrg 
28936ac495dSmrg       // These are needed for iterator_traits
29036ac495dSmrg       typedef std::random_access_iterator_tag                iterator_category;
29136ac495dSmrg       typedef typename _Unqualified_type<element_type>::type value_type;
29236ac495dSmrg       typedef std::ptrdiff_t                                 difference_type;
29336ac495dSmrg       typedef _Pointer_adapter                               pointer;
29436ac495dSmrg       typedef typename _Reference_type<element_type>::reference  reference;
29536ac495dSmrg 
29636ac495dSmrg       // Reminder: 'const' methods mean that the method is valid when the
29736ac495dSmrg       // pointer is immutable, and has nothing to do with whether the
29836ac495dSmrg       // 'pointee' is const.
29936ac495dSmrg 
30036ac495dSmrg       // Default Constructor (Convert from element_type*)
30136ac495dSmrg       _Pointer_adapter(element_type* __arg = 0)
30236ac495dSmrg       { _Storage_policy::set(__arg); }
30336ac495dSmrg 
30436ac495dSmrg       // Copy constructor from _Pointer_adapter of same type.
30536ac495dSmrg       _Pointer_adapter(const _Pointer_adapter& __arg)
30636ac495dSmrg       { _Storage_policy::set(__arg.get()); }
30736ac495dSmrg 
30836ac495dSmrg       // Convert from _Up* if conversion to element_type* is valid.
30936ac495dSmrg       template<typename _Up>
31036ac495dSmrg         _Pointer_adapter(_Up* __arg)
31136ac495dSmrg         { _Storage_policy::set(__arg); }
31236ac495dSmrg 
31336ac495dSmrg       // Conversion from another _Pointer_adapter if _Up if static cast is
31436ac495dSmrg       // valid.
31536ac495dSmrg       template<typename _Up>
31636ac495dSmrg         _Pointer_adapter(const _Pointer_adapter<_Up>& __arg)
31736ac495dSmrg         { _Storage_policy::set(__arg.get()); }
31836ac495dSmrg 
31936ac495dSmrg       // Destructor
32036ac495dSmrg       ~_Pointer_adapter() { }
32136ac495dSmrg 
32236ac495dSmrg       // Assignment operator
32336ac495dSmrg       _Pointer_adapter&
32436ac495dSmrg       operator=(const _Pointer_adapter& __arg)
32536ac495dSmrg       {
32636ac495dSmrg         _Storage_policy::set(__arg.get());
32736ac495dSmrg         return *this;
32836ac495dSmrg       }
32936ac495dSmrg 
33036ac495dSmrg       template<typename _Up>
33136ac495dSmrg         _Pointer_adapter&
33236ac495dSmrg         operator=(const _Pointer_adapter<_Up>& __arg)
33336ac495dSmrg         {
33436ac495dSmrg           _Storage_policy::set(__arg.get());
33536ac495dSmrg           return *this;
33636ac495dSmrg         }
33736ac495dSmrg 
33836ac495dSmrg       template<typename _Up>
33936ac495dSmrg         _Pointer_adapter&
34036ac495dSmrg         operator=(_Up* __arg)
34136ac495dSmrg         {
34236ac495dSmrg           _Storage_policy::set(__arg);
34336ac495dSmrg           return *this;
34436ac495dSmrg         }
34536ac495dSmrg 
34636ac495dSmrg       // Operator*, returns element_type&
34736ac495dSmrg       inline reference
34836ac495dSmrg       operator*() const
34936ac495dSmrg       { return *(_Storage_policy::get()); }
35036ac495dSmrg 
35136ac495dSmrg       // Operator->, returns element_type*
35236ac495dSmrg       inline element_type*
35336ac495dSmrg       operator->() const
35436ac495dSmrg       { return _Storage_policy::get(); }
35536ac495dSmrg 
35636ac495dSmrg       // Operator[], returns a element_type& to the item at that loc.
35736ac495dSmrg       inline reference
35836ac495dSmrg       operator[](std::ptrdiff_t __index) const
35936ac495dSmrg       { return _Storage_policy::get()[__index]; }
36036ac495dSmrg 
36136ac495dSmrg       // To allow implicit conversion to "bool", for "if (ptr)..."
362c0a68be4Smrg #if __cplusplus >= 201103L
363c0a68be4Smrg       explicit operator bool() const { return _Storage_policy::get() != 0; }
364c0a68be4Smrg #else
36536ac495dSmrg     private:
36636ac495dSmrg       typedef element_type*(_Pointer_adapter::*__unspecified_bool_type)() const;
36736ac495dSmrg 
36836ac495dSmrg     public:
36936ac495dSmrg       operator __unspecified_bool_type() const
37036ac495dSmrg       {
37136ac495dSmrg         return _Storage_policy::get() == 0 ? 0 :
37236ac495dSmrg                          &_Pointer_adapter::operator->;
37336ac495dSmrg       }
37436ac495dSmrg 
37536ac495dSmrg       // ! operator (for: if (!ptr)...)
37636ac495dSmrg       inline bool
37736ac495dSmrg       operator!() const
37836ac495dSmrg       { return (_Storage_policy::get() == 0); }
379c0a68be4Smrg #endif
38036ac495dSmrg 
38136ac495dSmrg       // Pointer differences
38236ac495dSmrg       inline friend std::ptrdiff_t
38336ac495dSmrg       operator-(const _Pointer_adapter& __lhs, element_type* __rhs)
38436ac495dSmrg       { return (__lhs.get() - __rhs); }
38536ac495dSmrg 
38636ac495dSmrg       inline friend std::ptrdiff_t
38736ac495dSmrg       operator-(element_type* __lhs, const _Pointer_adapter& __rhs)
38836ac495dSmrg       { return (__lhs - __rhs.get()); }
38936ac495dSmrg 
39036ac495dSmrg       template<typename _Up>
39136ac495dSmrg         inline friend std::ptrdiff_t
39236ac495dSmrg         operator-(const _Pointer_adapter& __lhs, _Up* __rhs)
39336ac495dSmrg         { return (__lhs.get() - __rhs); }
39436ac495dSmrg 
39536ac495dSmrg       template<typename _Up>
39636ac495dSmrg         inline friend std::ptrdiff_t
39736ac495dSmrg         operator-(_Up* __lhs, const _Pointer_adapter& __rhs)
39836ac495dSmrg         { return (__lhs - __rhs.get()); }
39936ac495dSmrg 
40036ac495dSmrg       template<typename _Up>
40136ac495dSmrg         inline std::ptrdiff_t
40236ac495dSmrg         operator-(const _Pointer_adapter<_Up>& __rhs) const
40336ac495dSmrg         { return (_Storage_policy::get() - __rhs.get()); }
40436ac495dSmrg 
40536ac495dSmrg       // Pointer math
40636ac495dSmrg       // Note: There is a reason for all this overloading based on different
40736ac495dSmrg       // integer types.  In some libstdc++-v3 test cases, a templated
40836ac495dSmrg       // operator+ is declared which can match any types.  This operator
40936ac495dSmrg       // tends to "steal" the recognition of _Pointer_adapter's own operator+
41036ac495dSmrg       // unless the integer type matches perfectly.
41136ac495dSmrg 
41236ac495dSmrg #define _CXX_POINTER_ARITH_OPERATOR_SET(INT_TYPE) \
41336ac495dSmrg       inline friend _Pointer_adapter \
41436ac495dSmrg       operator+(const _Pointer_adapter& __lhs, INT_TYPE __offset) \
41536ac495dSmrg       { return _Pointer_adapter(__lhs.get() + __offset); } \
41636ac495dSmrg \
41736ac495dSmrg       inline friend _Pointer_adapter \
41836ac495dSmrg       operator+(INT_TYPE __offset, const _Pointer_adapter& __rhs) \
41936ac495dSmrg       { return _Pointer_adapter(__rhs.get() + __offset); } \
42036ac495dSmrg \
42136ac495dSmrg       inline friend _Pointer_adapter \
42236ac495dSmrg       operator-(const _Pointer_adapter& __lhs, INT_TYPE __offset) \
42336ac495dSmrg       { return _Pointer_adapter(__lhs.get() - __offset); } \
42436ac495dSmrg \
42536ac495dSmrg       inline _Pointer_adapter& \
42636ac495dSmrg       operator+=(INT_TYPE __offset) \
42736ac495dSmrg       { \
42836ac495dSmrg         _Storage_policy::set(_Storage_policy::get() + __offset); \
42936ac495dSmrg         return *this; \
43036ac495dSmrg       } \
43136ac495dSmrg \
43236ac495dSmrg       inline _Pointer_adapter& \
43336ac495dSmrg       operator-=(INT_TYPE __offset) \
43436ac495dSmrg       { \
43536ac495dSmrg         _Storage_policy::set(_Storage_policy::get() - __offset); \
43636ac495dSmrg         return *this; \
43736ac495dSmrg       } \
43836ac495dSmrg // END of _CXX_POINTER_ARITH_OPERATOR_SET macro
43936ac495dSmrg 
44036ac495dSmrg       // Expand into the various pointer arithmetic operators needed.
44136ac495dSmrg       _CXX_POINTER_ARITH_OPERATOR_SET(short);
44236ac495dSmrg       _CXX_POINTER_ARITH_OPERATOR_SET(unsigned short);
44336ac495dSmrg       _CXX_POINTER_ARITH_OPERATOR_SET(int);
44436ac495dSmrg       _CXX_POINTER_ARITH_OPERATOR_SET(unsigned int);
44536ac495dSmrg       _CXX_POINTER_ARITH_OPERATOR_SET(long);
44636ac495dSmrg       _CXX_POINTER_ARITH_OPERATOR_SET(unsigned long);
44736ac495dSmrg #ifdef _GLIBCXX_USE_LONG_LONG
44836ac495dSmrg       _CXX_POINTER_ARITH_OPERATOR_SET(long long);
44936ac495dSmrg       _CXX_POINTER_ARITH_OPERATOR_SET(unsigned long long);
45036ac495dSmrg #endif
45136ac495dSmrg 
45236ac495dSmrg       // Mathematical Manipulators
45336ac495dSmrg       inline _Pointer_adapter&
45436ac495dSmrg       operator++()
45536ac495dSmrg       {
45636ac495dSmrg         _Storage_policy::set(_Storage_policy::get() + 1);
45736ac495dSmrg         return *this;
45836ac495dSmrg       }
45936ac495dSmrg 
46036ac495dSmrg       inline _Pointer_adapter
46136ac495dSmrg       operator++(int)
46236ac495dSmrg       {
46336ac495dSmrg         _Pointer_adapter __tmp(*this);
46436ac495dSmrg         _Storage_policy::set(_Storage_policy::get() + 1);
46536ac495dSmrg         return __tmp;
46636ac495dSmrg       }
46736ac495dSmrg 
46836ac495dSmrg       inline _Pointer_adapter&
46936ac495dSmrg       operator--()
47036ac495dSmrg       {
47136ac495dSmrg         _Storage_policy::set(_Storage_policy::get() - 1);
47236ac495dSmrg         return *this;
47336ac495dSmrg       }
47436ac495dSmrg 
47536ac495dSmrg       inline _Pointer_adapter
47636ac495dSmrg       operator--(int)
47736ac495dSmrg       {
47836ac495dSmrg         _Pointer_adapter __tmp(*this);
47936ac495dSmrg         _Storage_policy::set(_Storage_policy::get() - 1);
48036ac495dSmrg         return __tmp;
48136ac495dSmrg       }
48236ac495dSmrg 
483*8feb0f0bSmrg #if __cpp_lib_three_way_comparison
484*8feb0f0bSmrg       friend std::strong_ordering
485*8feb0f0bSmrg       operator<=>(const _Pointer_adapter& __lhs, const _Pointer_adapter& __rhs)
486*8feb0f0bSmrg       noexcept
487*8feb0f0bSmrg       { return __lhs.get() <=> __rhs.get(); }
488*8feb0f0bSmrg #endif
48936ac495dSmrg     }; // class _Pointer_adapter
49036ac495dSmrg 
49136ac495dSmrg 
49236ac495dSmrg #define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(OPERATOR) \
49336ac495dSmrg   template<typename _Tp1, typename _Tp2> \
49436ac495dSmrg     inline bool \
49536ac495dSmrg     operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, _Tp2 __rhs) \
49636ac495dSmrg     { return __lhs.get() OPERATOR __rhs; } \
49736ac495dSmrg \
49836ac495dSmrg   template<typename _Tp1, typename _Tp2> \
49936ac495dSmrg     inline bool \
50036ac495dSmrg     operator OPERATOR(_Tp1 __lhs, const _Pointer_adapter<_Tp2>& __rhs) \
50136ac495dSmrg     { return __lhs OPERATOR __rhs.get(); } \
50236ac495dSmrg \
50336ac495dSmrg   template<typename _Tp1, typename _Tp2> \
50436ac495dSmrg     inline bool \
50536ac495dSmrg     operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, \
50636ac495dSmrg                               const _Pointer_adapter<_Tp2>& __rhs) \
50736ac495dSmrg     { return __lhs.get() OPERATOR __rhs.get(); } \
50836ac495dSmrg \
50936ac495dSmrg // End GCC_CXX_POINTER_COMPARISON_OPERATION_SET Macro
51036ac495dSmrg 
51136ac495dSmrg   // Expand into the various comparison operators needed.
51236ac495dSmrg   _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(==)
51336ac495dSmrg   _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(!=)
51436ac495dSmrg   _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<)
51536ac495dSmrg   _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<=)
51636ac495dSmrg   _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>)
51736ac495dSmrg   _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>=)
51836ac495dSmrg 
51936ac495dSmrg   // These are here for expressions like "ptr == 0", "ptr != 0"
52036ac495dSmrg   template<typename _Tp>
52136ac495dSmrg     inline bool
52236ac495dSmrg     operator==(const _Pointer_adapter<_Tp>& __lhs, int __rhs)
52336ac495dSmrg     { return __lhs.get() == reinterpret_cast<void*>(__rhs); }
52436ac495dSmrg 
52536ac495dSmrg   template<typename _Tp>
52636ac495dSmrg     inline bool
52736ac495dSmrg     operator==(int __lhs, const _Pointer_adapter<_Tp>& __rhs)
52836ac495dSmrg     { return __rhs.get() == reinterpret_cast<void*>(__lhs); }
52936ac495dSmrg 
53036ac495dSmrg   template<typename _Tp>
53136ac495dSmrg     inline bool
53236ac495dSmrg     operator!=(const _Pointer_adapter<_Tp>& __lhs, int __rhs)
53336ac495dSmrg     { return __lhs.get() != reinterpret_cast<void*>(__rhs); }
53436ac495dSmrg 
53536ac495dSmrg   template<typename _Tp>
53636ac495dSmrg     inline bool
53736ac495dSmrg     operator!=(int __lhs, const _Pointer_adapter<_Tp>& __rhs)
53836ac495dSmrg     { return __rhs.get() != reinterpret_cast<void*>(__lhs); }
53936ac495dSmrg 
54036ac495dSmrg   /**
54136ac495dSmrg    * Comparison operators for _Pointer_adapter defer to the base class'
54236ac495dSmrg    * comparison operators, when possible.
54336ac495dSmrg    */
54436ac495dSmrg   template<typename _Tp>
54536ac495dSmrg     inline bool
54636ac495dSmrg     operator==(const _Pointer_adapter<_Tp>& __lhs,
54736ac495dSmrg                const _Pointer_adapter<_Tp>& __rhs)
54836ac495dSmrg     { return __lhs._Tp::operator==(__rhs); }
54936ac495dSmrg 
55036ac495dSmrg   template<typename _Tp>
55136ac495dSmrg     inline bool
55236ac495dSmrg     operator<=(const _Pointer_adapter<_Tp>& __lhs,
55336ac495dSmrg                const _Pointer_adapter<_Tp>& __rhs)
55436ac495dSmrg     { return __lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs); }
55536ac495dSmrg 
55636ac495dSmrg   template<typename _Tp>
55736ac495dSmrg     inline bool
55836ac495dSmrg     operator!=(const _Pointer_adapter<_Tp>& __lhs,
55936ac495dSmrg                const _Pointer_adapter<_Tp>& __rhs)
56036ac495dSmrg     { return !(__lhs._Tp::operator==(__rhs)); }
56136ac495dSmrg 
56236ac495dSmrg   template<typename _Tp>
56336ac495dSmrg     inline bool
56436ac495dSmrg     operator>(const _Pointer_adapter<_Tp>& __lhs,
56536ac495dSmrg               const _Pointer_adapter<_Tp>& __rhs)
56636ac495dSmrg     { return !(__lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs)); }
56736ac495dSmrg 
56836ac495dSmrg   template<typename _Tp>
56936ac495dSmrg     inline bool
57036ac495dSmrg     operator>=(const _Pointer_adapter<_Tp>& __lhs,
57136ac495dSmrg                const _Pointer_adapter<_Tp>& __rhs)
57236ac495dSmrg     { return !(__lhs._Tp::operator<(__rhs)); }
57336ac495dSmrg 
57436ac495dSmrg   template<typename _CharT, typename _Traits, typename _StoreT>
57536ac495dSmrg     inline std::basic_ostream<_CharT, _Traits>&
57636ac495dSmrg     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
57736ac495dSmrg                const _Pointer_adapter<_StoreT>& __p)
57836ac495dSmrg     { return (__os << __p.get()); }
57936ac495dSmrg 
58036ac495dSmrg _GLIBCXX_END_NAMESPACE_VERSION
58136ac495dSmrg } // namespace
58236ac495dSmrg 
58336ac495dSmrg #if __cplusplus >= 201103L
58436ac495dSmrg namespace std _GLIBCXX_VISIBILITY(default)
58536ac495dSmrg {
58636ac495dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
58736ac495dSmrg 
58836ac495dSmrg   template<typename _Storage_policy>
58936ac495dSmrg     struct pointer_traits<__gnu_cxx::_Pointer_adapter<_Storage_policy>>
59036ac495dSmrg     {
59136ac495dSmrg       /// The pointer type
59236ac495dSmrg       typedef __gnu_cxx::_Pointer_adapter<_Storage_policy>         pointer;
59336ac495dSmrg       /// The type pointed to
59436ac495dSmrg       typedef typename pointer::element_type            element_type;
59536ac495dSmrg       /// Type used to represent the difference between two pointers
59636ac495dSmrg       typedef typename pointer::difference_type         difference_type;
59736ac495dSmrg 
59836ac495dSmrg       template<typename _Up>
59936ac495dSmrg         using rebind = typename __gnu_cxx::_Pointer_adapter<
60036ac495dSmrg 	typename pointer_traits<_Storage_policy>::template rebind<_Up>>;
60136ac495dSmrg 
60236ac495dSmrg       static pointer pointer_to(typename pointer::reference __r) noexcept
60336ac495dSmrg       { return pointer(std::addressof(__r)); }
60436ac495dSmrg     };
60536ac495dSmrg 
606*8feb0f0bSmrg #if __cpp_lib_concepts
607*8feb0f0bSmrg   template<typename _Policy>
608*8feb0f0bSmrg     struct indirectly_readable_traits<__gnu_cxx::_Pointer_adapter<_Policy>>
609*8feb0f0bSmrg     {
610*8feb0f0bSmrg       using value_type
611*8feb0f0bSmrg 	= typename __gnu_cxx::_Pointer_adapter<_Policy>::value_type;
612*8feb0f0bSmrg     };
613*8feb0f0bSmrg #endif
61436ac495dSmrg _GLIBCXX_END_NAMESPACE_VERSION
61536ac495dSmrg } // namespace
61636ac495dSmrg #endif
61736ac495dSmrg 
61836ac495dSmrg #endif // _POINTER_H
619