1*38fd1498Szrj // Custom pointer adapter and sample storage policies 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2008-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj /** 26*38fd1498Szrj * @file ext/pointer.h 27*38fd1498Szrj * This file is a GNU extension to the Standard C++ Library. 28*38fd1498Szrj * 29*38fd1498Szrj * @author Bob Walters 30*38fd1498Szrj * 31*38fd1498Szrj * Provides reusable _Pointer_adapter for assisting in the development of 32*38fd1498Szrj * custom pointer types that can be used with the standard containers via 33*38fd1498Szrj * the allocator::pointer and allocator::const_pointer typedefs. 34*38fd1498Szrj */ 35*38fd1498Szrj 36*38fd1498Szrj #ifndef _POINTER_H 37*38fd1498Szrj #define _POINTER_H 1 38*38fd1498Szrj 39*38fd1498Szrj #pragma GCC system_header 40*38fd1498Szrj 41*38fd1498Szrj #include <iosfwd> 42*38fd1498Szrj #include <bits/stl_iterator_base_types.h> 43*38fd1498Szrj #include <ext/cast.h> 44*38fd1498Szrj #include <ext/type_traits.h> 45*38fd1498Szrj #if __cplusplus >= 201103L 46*38fd1498Szrj # include <bits/move.h> 47*38fd1498Szrj # include <bits/ptr_traits.h> 48*38fd1498Szrj #endif 49*38fd1498Szrj 50*38fd1498Szrj namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 51*38fd1498Szrj { 52*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 53*38fd1498Szrj 54*38fd1498Szrj /** 55*38fd1498Szrj * @brief A storage policy for use with _Pointer_adapter<> which yields a 56*38fd1498Szrj * standard pointer. 57*38fd1498Szrj * 58*38fd1498Szrj * A _Storage_policy is required to provide 4 things: 59*38fd1498Szrj * 1) A get() API for returning the stored pointer value. 60*38fd1498Szrj * 2) An set() API for storing a pointer value. 61*38fd1498Szrj * 3) An element_type typedef to define the type this points to. 62*38fd1498Szrj * 4) An operator<() to support pointer comparison. 63*38fd1498Szrj * 5) An operator==() to support pointer comparison. 64*38fd1498Szrj */ 65*38fd1498Szrj template<typename _Tp> 66*38fd1498Szrj class _Std_pointer_impl 67*38fd1498Szrj { 68*38fd1498Szrj public: 69*38fd1498Szrj // the type this pointer points to. 70*38fd1498Szrj typedef _Tp element_type; 71*38fd1498Szrj 72*38fd1498Szrj // A method to fetch the pointer value as a standard T* value; 73*38fd1498Szrj inline _Tp* 74*38fd1498Szrj get() const 75*38fd1498Szrj { return _M_value; } 76*38fd1498Szrj 77*38fd1498Szrj // A method to set the pointer value, from a standard T* value; 78*38fd1498Szrj inline void 79*38fd1498Szrj set(element_type* __arg) 80*38fd1498Szrj { _M_value = __arg; } 81*38fd1498Szrj 82*38fd1498Szrj // Comparison of pointers 83*38fd1498Szrj inline bool 84*38fd1498Szrj operator<(const _Std_pointer_impl& __rarg) const 85*38fd1498Szrj { return (_M_value < __rarg._M_value); } 86*38fd1498Szrj 87*38fd1498Szrj inline bool 88*38fd1498Szrj operator==(const _Std_pointer_impl& __rarg) const 89*38fd1498Szrj { return (_M_value == __rarg._M_value); } 90*38fd1498Szrj 91*38fd1498Szrj private: 92*38fd1498Szrj element_type* _M_value; 93*38fd1498Szrj }; 94*38fd1498Szrj 95*38fd1498Szrj /** 96*38fd1498Szrj * @brief A storage policy for use with _Pointer_adapter<> which stores 97*38fd1498Szrj * the pointer's address as an offset value which is relative to 98*38fd1498Szrj * its own address. 99*38fd1498Szrj * 100*38fd1498Szrj * This is intended for pointers within shared memory regions which 101*38fd1498Szrj * might be mapped at different addresses by different processes. 102*38fd1498Szrj * For null pointers, a value of 1 is used. (0 is legitimate 103*38fd1498Szrj * sometimes for nodes in circularly linked lists) This value was 104*38fd1498Szrj * chosen as the least likely to generate an incorrect null, As 105*38fd1498Szrj * there is no reason why any normal pointer would point 1 byte into 106*38fd1498Szrj * its own pointer address. 107*38fd1498Szrj */ 108*38fd1498Szrj template<typename _Tp> 109*38fd1498Szrj class _Relative_pointer_impl 110*38fd1498Szrj { 111*38fd1498Szrj public: 112*38fd1498Szrj typedef _Tp element_type; 113*38fd1498Szrj 114*38fd1498Szrj _Tp* 115*38fd1498Szrj get() const 116*38fd1498Szrj { 117*38fd1498Szrj if (_M_diff == 1) 118*38fd1498Szrj return 0; 119*38fd1498Szrj else 120*38fd1498Szrj return reinterpret_cast<_Tp*>(reinterpret_cast<_UIntPtrType>(this) 121*38fd1498Szrj + _M_diff); 122*38fd1498Szrj } 123*38fd1498Szrj 124*38fd1498Szrj void 125*38fd1498Szrj set(_Tp* __arg) 126*38fd1498Szrj { 127*38fd1498Szrj if (!__arg) 128*38fd1498Szrj _M_diff = 1; 129*38fd1498Szrj else 130*38fd1498Szrj _M_diff = reinterpret_cast<_UIntPtrType>(__arg) 131*38fd1498Szrj - reinterpret_cast<_UIntPtrType>(this); 132*38fd1498Szrj } 133*38fd1498Szrj 134*38fd1498Szrj // Comparison of pointers 135*38fd1498Szrj inline bool 136*38fd1498Szrj operator<(const _Relative_pointer_impl& __rarg) const 137*38fd1498Szrj { return (reinterpret_cast<_UIntPtrType>(this->get()) 138*38fd1498Szrj < reinterpret_cast<_UIntPtrType>(__rarg.get())); } 139*38fd1498Szrj 140*38fd1498Szrj inline bool 141*38fd1498Szrj operator==(const _Relative_pointer_impl& __rarg) const 142*38fd1498Szrj { return (reinterpret_cast<_UIntPtrType>(this->get()) 143*38fd1498Szrj == reinterpret_cast<_UIntPtrType>(__rarg.get())); } 144*38fd1498Szrj 145*38fd1498Szrj private: 146*38fd1498Szrj #ifdef _GLIBCXX_USE_LONG_LONG 147*38fd1498Szrj typedef __gnu_cxx::__conditional_type< 148*38fd1498Szrj (sizeof(unsigned long) >= sizeof(void*)), 149*38fd1498Szrj unsigned long, unsigned long long>::__type _UIntPtrType; 150*38fd1498Szrj #else 151*38fd1498Szrj typedef unsigned long _UIntPtrType; 152*38fd1498Szrj #endif 153*38fd1498Szrj _UIntPtrType _M_diff; 154*38fd1498Szrj }; 155*38fd1498Szrj 156*38fd1498Szrj /** 157*38fd1498Szrj * Relative_pointer_impl needs a specialization for const T because of 158*38fd1498Szrj * the casting done during pointer arithmetic. 159*38fd1498Szrj */ 160*38fd1498Szrj template<typename _Tp> 161*38fd1498Szrj class _Relative_pointer_impl<const _Tp> 162*38fd1498Szrj { 163*38fd1498Szrj public: 164*38fd1498Szrj typedef const _Tp element_type; 165*38fd1498Szrj 166*38fd1498Szrj const _Tp* 167*38fd1498Szrj get() const 168*38fd1498Szrj { 169*38fd1498Szrj if (_M_diff == 1) 170*38fd1498Szrj return 0; 171*38fd1498Szrj else 172*38fd1498Szrj return reinterpret_cast<const _Tp*> 173*38fd1498Szrj (reinterpret_cast<_UIntPtrType>(this) + _M_diff); 174*38fd1498Szrj } 175*38fd1498Szrj 176*38fd1498Szrj void 177*38fd1498Szrj set(const _Tp* __arg) 178*38fd1498Szrj { 179*38fd1498Szrj if (!__arg) 180*38fd1498Szrj _M_diff = 1; 181*38fd1498Szrj else 182*38fd1498Szrj _M_diff = reinterpret_cast<_UIntPtrType>(__arg) 183*38fd1498Szrj - reinterpret_cast<_UIntPtrType>(this); 184*38fd1498Szrj } 185*38fd1498Szrj 186*38fd1498Szrj // Comparison of pointers 187*38fd1498Szrj inline bool 188*38fd1498Szrj operator<(const _Relative_pointer_impl& __rarg) const 189*38fd1498Szrj { return (reinterpret_cast<_UIntPtrType>(this->get()) 190*38fd1498Szrj < reinterpret_cast<_UIntPtrType>(__rarg.get())); } 191*38fd1498Szrj 192*38fd1498Szrj inline bool 193*38fd1498Szrj operator==(const _Relative_pointer_impl& __rarg) const 194*38fd1498Szrj { return (reinterpret_cast<_UIntPtrType>(this->get()) 195*38fd1498Szrj == reinterpret_cast<_UIntPtrType>(__rarg.get())); } 196*38fd1498Szrj 197*38fd1498Szrj private: 198*38fd1498Szrj #ifdef _GLIBCXX_USE_LONG_LONG 199*38fd1498Szrj typedef __gnu_cxx::__conditional_type< 200*38fd1498Szrj (sizeof(unsigned long) >= sizeof(void*)), 201*38fd1498Szrj unsigned long, unsigned long long>::__type _UIntPtrType; 202*38fd1498Szrj #else 203*38fd1498Szrj typedef unsigned long _UIntPtrType; 204*38fd1498Szrj #endif 205*38fd1498Szrj _UIntPtrType _M_diff; 206*38fd1498Szrj }; 207*38fd1498Szrj 208*38fd1498Szrj /** 209*38fd1498Szrj * The specialization on this type helps resolve the problem of 210*38fd1498Szrj * reference to void, and eliminates the need to specialize 211*38fd1498Szrj * _Pointer_adapter for cases of void*, const void*, and so on. 212*38fd1498Szrj */ 213*38fd1498Szrj struct _Invalid_type { }; 214*38fd1498Szrj 215*38fd1498Szrj template<typename _Tp> 216*38fd1498Szrj struct _Reference_type 217*38fd1498Szrj { typedef _Tp& reference; }; 218*38fd1498Szrj 219*38fd1498Szrj template<> 220*38fd1498Szrj struct _Reference_type<void> 221*38fd1498Szrj { typedef _Invalid_type& reference; }; 222*38fd1498Szrj 223*38fd1498Szrj template<> 224*38fd1498Szrj struct _Reference_type<const void> 225*38fd1498Szrj { typedef const _Invalid_type& reference; }; 226*38fd1498Szrj 227*38fd1498Szrj template<> 228*38fd1498Szrj struct _Reference_type<volatile void> 229*38fd1498Szrj { typedef volatile _Invalid_type& reference; }; 230*38fd1498Szrj 231*38fd1498Szrj template<> 232*38fd1498Szrj struct _Reference_type<volatile const void> 233*38fd1498Szrj { typedef const volatile _Invalid_type& reference; }; 234*38fd1498Szrj 235*38fd1498Szrj /** 236*38fd1498Szrj * This structure accommodates the way in which 237*38fd1498Szrj * std::iterator_traits<> is normally specialized for const T*, so 238*38fd1498Szrj * that value_type is still T. 239*38fd1498Szrj */ 240*38fd1498Szrj template<typename _Tp> 241*38fd1498Szrj struct _Unqualified_type 242*38fd1498Szrj { typedef _Tp type; }; 243*38fd1498Szrj 244*38fd1498Szrj template<typename _Tp> 245*38fd1498Szrj struct _Unqualified_type<const _Tp> 246*38fd1498Szrj { typedef _Tp type; }; 247*38fd1498Szrj 248*38fd1498Szrj /** 249*38fd1498Szrj * The following provides an 'alternative pointer' that works with 250*38fd1498Szrj * the containers when specified as the pointer typedef of the 251*38fd1498Szrj * allocator. 252*38fd1498Szrj * 253*38fd1498Szrj * The pointer type used with the containers doesn't have to be this 254*38fd1498Szrj * class, but it must support the implicit conversions, pointer 255*38fd1498Szrj * arithmetic, comparison operators, etc. that are supported by this 256*38fd1498Szrj * class, and avoid raising compile-time ambiguities. Because 257*38fd1498Szrj * creating a working pointer can be challenging, this pointer 258*38fd1498Szrj * template was designed to wrapper an easier storage policy type, 259*38fd1498Szrj * so that it becomes reusable for creating other pointer types. 260*38fd1498Szrj * 261*38fd1498Szrj * A key point of this class is also that it allows container 262*38fd1498Szrj * writers to 'assume' Allocator::pointer is a typedef for a normal 263*38fd1498Szrj * pointer. This class supports most of the conventions of a true 264*38fd1498Szrj * pointer, and can, for instance handle implicit conversion to 265*38fd1498Szrj * const and base class pointer types. The only impositions on 266*38fd1498Szrj * container writers to support extended pointers are: 1) use the 267*38fd1498Szrj * Allocator::pointer typedef appropriately for pointer types. 2) 268*38fd1498Szrj * if you need pointer casting, use the __pointer_cast<> functions 269*38fd1498Szrj * from ext/cast.h. This allows pointer cast operations to be 270*38fd1498Szrj * overloaded as necessary by custom pointers. 271*38fd1498Szrj * 272*38fd1498Szrj * Note: The const qualifier works with this pointer adapter as 273*38fd1498Szrj * follows: 274*38fd1498Szrj * 275*38fd1498Szrj * _Tp* == _Pointer_adapter<_Std_pointer_impl<_Tp> >; 276*38fd1498Szrj * const _Tp* == _Pointer_adapter<_Std_pointer_impl<const _Tp> >; 277*38fd1498Szrj * _Tp* const == const _Pointer_adapter<_Std_pointer_impl<_Tp> >; 278*38fd1498Szrj * const _Tp* const == const _Pointer_adapter<_Std_pointer_impl<const _Tp> >; 279*38fd1498Szrj */ 280*38fd1498Szrj template<typename _Storage_policy> 281*38fd1498Szrj class _Pointer_adapter : public _Storage_policy 282*38fd1498Szrj { 283*38fd1498Szrj public: 284*38fd1498Szrj typedef typename _Storage_policy::element_type element_type; 285*38fd1498Szrj 286*38fd1498Szrj // These are needed for iterator_traits 287*38fd1498Szrj typedef std::random_access_iterator_tag iterator_category; 288*38fd1498Szrj typedef typename _Unqualified_type<element_type>::type value_type; 289*38fd1498Szrj typedef std::ptrdiff_t difference_type; 290*38fd1498Szrj typedef _Pointer_adapter pointer; 291*38fd1498Szrj typedef typename _Reference_type<element_type>::reference reference; 292*38fd1498Szrj 293*38fd1498Szrj // Reminder: 'const' methods mean that the method is valid when the 294*38fd1498Szrj // pointer is immutable, and has nothing to do with whether the 295*38fd1498Szrj // 'pointee' is const. 296*38fd1498Szrj 297*38fd1498Szrj // Default Constructor (Convert from element_type*) 298*38fd1498Szrj _Pointer_adapter(element_type* __arg = 0) 299*38fd1498Szrj { _Storage_policy::set(__arg); } 300*38fd1498Szrj 301*38fd1498Szrj // Copy constructor from _Pointer_adapter of same type. 302*38fd1498Szrj _Pointer_adapter(const _Pointer_adapter& __arg) 303*38fd1498Szrj { _Storage_policy::set(__arg.get()); } 304*38fd1498Szrj 305*38fd1498Szrj // Convert from _Up* if conversion to element_type* is valid. 306*38fd1498Szrj template<typename _Up> 307*38fd1498Szrj _Pointer_adapter(_Up* __arg) 308*38fd1498Szrj { _Storage_policy::set(__arg); } 309*38fd1498Szrj 310*38fd1498Szrj // Conversion from another _Pointer_adapter if _Up if static cast is 311*38fd1498Szrj // valid. 312*38fd1498Szrj template<typename _Up> 313*38fd1498Szrj _Pointer_adapter(const _Pointer_adapter<_Up>& __arg) 314*38fd1498Szrj { _Storage_policy::set(__arg.get()); } 315*38fd1498Szrj 316*38fd1498Szrj // Destructor 317*38fd1498Szrj ~_Pointer_adapter() { } 318*38fd1498Szrj 319*38fd1498Szrj // Assignment operator 320*38fd1498Szrj _Pointer_adapter& 321*38fd1498Szrj operator=(const _Pointer_adapter& __arg) 322*38fd1498Szrj { 323*38fd1498Szrj _Storage_policy::set(__arg.get()); 324*38fd1498Szrj return *this; 325*38fd1498Szrj } 326*38fd1498Szrj 327*38fd1498Szrj template<typename _Up> 328*38fd1498Szrj _Pointer_adapter& 329*38fd1498Szrj operator=(const _Pointer_adapter<_Up>& __arg) 330*38fd1498Szrj { 331*38fd1498Szrj _Storage_policy::set(__arg.get()); 332*38fd1498Szrj return *this; 333*38fd1498Szrj } 334*38fd1498Szrj 335*38fd1498Szrj template<typename _Up> 336*38fd1498Szrj _Pointer_adapter& 337*38fd1498Szrj operator=(_Up* __arg) 338*38fd1498Szrj { 339*38fd1498Szrj _Storage_policy::set(__arg); 340*38fd1498Szrj return *this; 341*38fd1498Szrj } 342*38fd1498Szrj 343*38fd1498Szrj // Operator*, returns element_type& 344*38fd1498Szrj inline reference 345*38fd1498Szrj operator*() const 346*38fd1498Szrj { return *(_Storage_policy::get()); } 347*38fd1498Szrj 348*38fd1498Szrj // Operator->, returns element_type* 349*38fd1498Szrj inline element_type* 350*38fd1498Szrj operator->() const 351*38fd1498Szrj { return _Storage_policy::get(); } 352*38fd1498Szrj 353*38fd1498Szrj // Operator[], returns a element_type& to the item at that loc. 354*38fd1498Szrj inline reference 355*38fd1498Szrj operator[](std::ptrdiff_t __index) const 356*38fd1498Szrj { return _Storage_policy::get()[__index]; } 357*38fd1498Szrj 358*38fd1498Szrj // To allow implicit conversion to "bool", for "if (ptr)..." 359*38fd1498Szrj private: 360*38fd1498Szrj typedef element_type*(_Pointer_adapter::*__unspecified_bool_type)() const; 361*38fd1498Szrj 362*38fd1498Szrj public: 363*38fd1498Szrj operator __unspecified_bool_type() const 364*38fd1498Szrj { 365*38fd1498Szrj return _Storage_policy::get() == 0 ? 0 : 366*38fd1498Szrj &_Pointer_adapter::operator->; 367*38fd1498Szrj } 368*38fd1498Szrj 369*38fd1498Szrj // ! operator (for: if (!ptr)...) 370*38fd1498Szrj inline bool 371*38fd1498Szrj operator!() const 372*38fd1498Szrj { return (_Storage_policy::get() == 0); } 373*38fd1498Szrj 374*38fd1498Szrj // Pointer differences 375*38fd1498Szrj inline friend std::ptrdiff_t 376*38fd1498Szrj operator-(const _Pointer_adapter& __lhs, element_type* __rhs) 377*38fd1498Szrj { return (__lhs.get() - __rhs); } 378*38fd1498Szrj 379*38fd1498Szrj inline friend std::ptrdiff_t 380*38fd1498Szrj operator-(element_type* __lhs, const _Pointer_adapter& __rhs) 381*38fd1498Szrj { return (__lhs - __rhs.get()); } 382*38fd1498Szrj 383*38fd1498Szrj template<typename _Up> 384*38fd1498Szrj inline friend std::ptrdiff_t 385*38fd1498Szrj operator-(const _Pointer_adapter& __lhs, _Up* __rhs) 386*38fd1498Szrj { return (__lhs.get() - __rhs); } 387*38fd1498Szrj 388*38fd1498Szrj template<typename _Up> 389*38fd1498Szrj inline friend std::ptrdiff_t 390*38fd1498Szrj operator-(_Up* __lhs, const _Pointer_adapter& __rhs) 391*38fd1498Szrj { return (__lhs - __rhs.get()); } 392*38fd1498Szrj 393*38fd1498Szrj template<typename _Up> 394*38fd1498Szrj inline std::ptrdiff_t 395*38fd1498Szrj operator-(const _Pointer_adapter<_Up>& __rhs) const 396*38fd1498Szrj { return (_Storage_policy::get() - __rhs.get()); } 397*38fd1498Szrj 398*38fd1498Szrj // Pointer math 399*38fd1498Szrj // Note: There is a reason for all this overloading based on different 400*38fd1498Szrj // integer types. In some libstdc++-v3 test cases, a templated 401*38fd1498Szrj // operator+ is declared which can match any types. This operator 402*38fd1498Szrj // tends to "steal" the recognition of _Pointer_adapter's own operator+ 403*38fd1498Szrj // unless the integer type matches perfectly. 404*38fd1498Szrj 405*38fd1498Szrj #define _CXX_POINTER_ARITH_OPERATOR_SET(INT_TYPE) \ 406*38fd1498Szrj inline friend _Pointer_adapter \ 407*38fd1498Szrj operator+(const _Pointer_adapter& __lhs, INT_TYPE __offset) \ 408*38fd1498Szrj { return _Pointer_adapter(__lhs.get() + __offset); } \ 409*38fd1498Szrj \ 410*38fd1498Szrj inline friend _Pointer_adapter \ 411*38fd1498Szrj operator+(INT_TYPE __offset, const _Pointer_adapter& __rhs) \ 412*38fd1498Szrj { return _Pointer_adapter(__rhs.get() + __offset); } \ 413*38fd1498Szrj \ 414*38fd1498Szrj inline friend _Pointer_adapter \ 415*38fd1498Szrj operator-(const _Pointer_adapter& __lhs, INT_TYPE __offset) \ 416*38fd1498Szrj { return _Pointer_adapter(__lhs.get() - __offset); } \ 417*38fd1498Szrj \ 418*38fd1498Szrj inline _Pointer_adapter& \ 419*38fd1498Szrj operator+=(INT_TYPE __offset) \ 420*38fd1498Szrj { \ 421*38fd1498Szrj _Storage_policy::set(_Storage_policy::get() + __offset); \ 422*38fd1498Szrj return *this; \ 423*38fd1498Szrj } \ 424*38fd1498Szrj \ 425*38fd1498Szrj inline _Pointer_adapter& \ 426*38fd1498Szrj operator-=(INT_TYPE __offset) \ 427*38fd1498Szrj { \ 428*38fd1498Szrj _Storage_policy::set(_Storage_policy::get() - __offset); \ 429*38fd1498Szrj return *this; \ 430*38fd1498Szrj } \ 431*38fd1498Szrj // END of _CXX_POINTER_ARITH_OPERATOR_SET macro 432*38fd1498Szrj 433*38fd1498Szrj // Expand into the various pointer arithmetic operators needed. 434*38fd1498Szrj _CXX_POINTER_ARITH_OPERATOR_SET(short); 435*38fd1498Szrj _CXX_POINTER_ARITH_OPERATOR_SET(unsigned short); 436*38fd1498Szrj _CXX_POINTER_ARITH_OPERATOR_SET(int); 437*38fd1498Szrj _CXX_POINTER_ARITH_OPERATOR_SET(unsigned int); 438*38fd1498Szrj _CXX_POINTER_ARITH_OPERATOR_SET(long); 439*38fd1498Szrj _CXX_POINTER_ARITH_OPERATOR_SET(unsigned long); 440*38fd1498Szrj 441*38fd1498Szrj // Mathematical Manipulators 442*38fd1498Szrj inline _Pointer_adapter& 443*38fd1498Szrj operator++() 444*38fd1498Szrj { 445*38fd1498Szrj _Storage_policy::set(_Storage_policy::get() + 1); 446*38fd1498Szrj return *this; 447*38fd1498Szrj } 448*38fd1498Szrj 449*38fd1498Szrj inline _Pointer_adapter 450*38fd1498Szrj operator++(int) 451*38fd1498Szrj { 452*38fd1498Szrj _Pointer_adapter __tmp(*this); 453*38fd1498Szrj _Storage_policy::set(_Storage_policy::get() + 1); 454*38fd1498Szrj return __tmp; 455*38fd1498Szrj } 456*38fd1498Szrj 457*38fd1498Szrj inline _Pointer_adapter& 458*38fd1498Szrj operator--() 459*38fd1498Szrj { 460*38fd1498Szrj _Storage_policy::set(_Storage_policy::get() - 1); 461*38fd1498Szrj return *this; 462*38fd1498Szrj } 463*38fd1498Szrj 464*38fd1498Szrj inline _Pointer_adapter 465*38fd1498Szrj operator--(int) 466*38fd1498Szrj { 467*38fd1498Szrj _Pointer_adapter __tmp(*this); 468*38fd1498Szrj _Storage_policy::set(_Storage_policy::get() - 1); 469*38fd1498Szrj return __tmp; 470*38fd1498Szrj } 471*38fd1498Szrj 472*38fd1498Szrj }; // class _Pointer_adapter 473*38fd1498Szrj 474*38fd1498Szrj 475*38fd1498Szrj #define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(OPERATOR) \ 476*38fd1498Szrj template<typename _Tp1, typename _Tp2> \ 477*38fd1498Szrj inline bool \ 478*38fd1498Szrj operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, _Tp2 __rhs) \ 479*38fd1498Szrj { return __lhs.get() OPERATOR __rhs; } \ 480*38fd1498Szrj \ 481*38fd1498Szrj template<typename _Tp1, typename _Tp2> \ 482*38fd1498Szrj inline bool \ 483*38fd1498Szrj operator OPERATOR(_Tp1 __lhs, const _Pointer_adapter<_Tp2>& __rhs) \ 484*38fd1498Szrj { return __lhs OPERATOR __rhs.get(); } \ 485*38fd1498Szrj \ 486*38fd1498Szrj template<typename _Tp1, typename _Tp2> \ 487*38fd1498Szrj inline bool \ 488*38fd1498Szrj operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, \ 489*38fd1498Szrj const _Pointer_adapter<_Tp2>& __rhs) \ 490*38fd1498Szrj { return __lhs.get() OPERATOR __rhs.get(); } \ 491*38fd1498Szrj \ 492*38fd1498Szrj // End GCC_CXX_POINTER_COMPARISON_OPERATION_SET Macro 493*38fd1498Szrj 494*38fd1498Szrj // Expand into the various comparison operators needed. 495*38fd1498Szrj _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(==) 496*38fd1498Szrj _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(!=) 497*38fd1498Szrj _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<) 498*38fd1498Szrj _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<=) 499*38fd1498Szrj _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>) 500*38fd1498Szrj _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>=) 501*38fd1498Szrj 502*38fd1498Szrj // These are here for expressions like "ptr == 0", "ptr != 0" 503*38fd1498Szrj template<typename _Tp> 504*38fd1498Szrj inline bool 505*38fd1498Szrj operator==(const _Pointer_adapter<_Tp>& __lhs, int __rhs) 506*38fd1498Szrj { return __lhs.get() == reinterpret_cast<void*>(__rhs); } 507*38fd1498Szrj 508*38fd1498Szrj template<typename _Tp> 509*38fd1498Szrj inline bool 510*38fd1498Szrj operator==(int __lhs, const _Pointer_adapter<_Tp>& __rhs) 511*38fd1498Szrj { return __rhs.get() == reinterpret_cast<void*>(__lhs); } 512*38fd1498Szrj 513*38fd1498Szrj template<typename _Tp> 514*38fd1498Szrj inline bool 515*38fd1498Szrj operator!=(const _Pointer_adapter<_Tp>& __lhs, int __rhs) 516*38fd1498Szrj { return __lhs.get() != reinterpret_cast<void*>(__rhs); } 517*38fd1498Szrj 518*38fd1498Szrj template<typename _Tp> 519*38fd1498Szrj inline bool 520*38fd1498Szrj operator!=(int __lhs, const _Pointer_adapter<_Tp>& __rhs) 521*38fd1498Szrj { return __rhs.get() != reinterpret_cast<void*>(__lhs); } 522*38fd1498Szrj 523*38fd1498Szrj /** 524*38fd1498Szrj * Comparison operators for _Pointer_adapter defer to the base class' 525*38fd1498Szrj * comparison operators, when possible. 526*38fd1498Szrj */ 527*38fd1498Szrj template<typename _Tp> 528*38fd1498Szrj inline bool 529*38fd1498Szrj operator==(const _Pointer_adapter<_Tp>& __lhs, 530*38fd1498Szrj const _Pointer_adapter<_Tp>& __rhs) 531*38fd1498Szrj { return __lhs._Tp::operator==(__rhs); } 532*38fd1498Szrj 533*38fd1498Szrj template<typename _Tp> 534*38fd1498Szrj inline bool 535*38fd1498Szrj operator<=(const _Pointer_adapter<_Tp>& __lhs, 536*38fd1498Szrj const _Pointer_adapter<_Tp>& __rhs) 537*38fd1498Szrj { return __lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs); } 538*38fd1498Szrj 539*38fd1498Szrj template<typename _Tp> 540*38fd1498Szrj inline bool 541*38fd1498Szrj operator!=(const _Pointer_adapter<_Tp>& __lhs, 542*38fd1498Szrj const _Pointer_adapter<_Tp>& __rhs) 543*38fd1498Szrj { return !(__lhs._Tp::operator==(__rhs)); } 544*38fd1498Szrj 545*38fd1498Szrj template<typename _Tp> 546*38fd1498Szrj inline bool 547*38fd1498Szrj operator>(const _Pointer_adapter<_Tp>& __lhs, 548*38fd1498Szrj const _Pointer_adapter<_Tp>& __rhs) 549*38fd1498Szrj { return !(__lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs)); } 550*38fd1498Szrj 551*38fd1498Szrj template<typename _Tp> 552*38fd1498Szrj inline bool 553*38fd1498Szrj operator>=(const _Pointer_adapter<_Tp>& __lhs, 554*38fd1498Szrj const _Pointer_adapter<_Tp>& __rhs) 555*38fd1498Szrj { return !(__lhs._Tp::operator<(__rhs)); } 556*38fd1498Szrj 557*38fd1498Szrj template<typename _CharT, typename _Traits, typename _StoreT> 558*38fd1498Szrj inline std::basic_ostream<_CharT, _Traits>& 559*38fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 560*38fd1498Szrj const _Pointer_adapter<_StoreT>& __p) 561*38fd1498Szrj { return (__os << __p.get()); } 562*38fd1498Szrj 563*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 564*38fd1498Szrj } // namespace 565*38fd1498Szrj 566*38fd1498Szrj #if __cplusplus >= 201103L 567*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 568*38fd1498Szrj { 569*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 570*38fd1498Szrj 571*38fd1498Szrj template<typename _Storage_policy> 572*38fd1498Szrj struct pointer_traits<__gnu_cxx::_Pointer_adapter<_Storage_policy>> 573*38fd1498Szrj { 574*38fd1498Szrj /// The pointer type 575*38fd1498Szrj typedef __gnu_cxx::_Pointer_adapter<_Storage_policy> pointer; 576*38fd1498Szrj /// The type pointed to 577*38fd1498Szrj typedef typename pointer::element_type element_type; 578*38fd1498Szrj /// Type used to represent the difference between two pointers 579*38fd1498Szrj typedef typename pointer::difference_type difference_type; 580*38fd1498Szrj 581*38fd1498Szrj template<typename _Up> 582*38fd1498Szrj using rebind = typename __gnu_cxx::_Pointer_adapter< 583*38fd1498Szrj typename pointer_traits<_Storage_policy>::template rebind<_Up>>; 584*38fd1498Szrj 585*38fd1498Szrj static pointer pointer_to(typename pointer::reference __r) noexcept 586*38fd1498Szrj { return pointer(std::addressof(__r)); } 587*38fd1498Szrj }; 588*38fd1498Szrj 589*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 590*38fd1498Szrj } // namespace 591*38fd1498Szrj #endif 592*38fd1498Szrj 593*38fd1498Szrj #endif // _POINTER_H 594