111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Custom pointer adapter and sample storage policies 211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Copyright (C) 2008-2014 Free Software Foundation, Inc. 411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This file is part of the GNU ISO C++ Library. This library is free 611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// software; you can redistribute it and/or modify it under the 711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// terms of the GNU General Public License as published by the 811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Free Software Foundation; either version 3, or (at your option) 911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// any later version. 1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This library is distributed in the hope that it will be useful, 1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// but WITHOUT ANY WARRANTY; without even the implied warranty of 1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// GNU General Public License for more details. 1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Under Section 7 of GPL version 3, you are granted additional 1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// permissions described in the GCC Runtime Library Exception, version 1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 3.1, as published by the Free Software Foundation. 1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// You should have received a copy of the GNU General Public License and 2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// a copy of the GCC Runtime Library Exception along with this program; 2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// <http://www.gnu.org/licenses/>. 2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/** 2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * @file ext/pointer.h 2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This file is a GNU extension to the Standard C++ Library. 2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * @author Bob Walters 3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Provides reusable _Pointer_adapter for assisting in the development of 3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * custom pointer types that can be used with the standard containers via 3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * the allocator::pointer and allocator::const_pointer typedefs. 3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _POINTER_H 3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define _POINTER_H 1 3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#pragma GCC system_header 4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <iosfwd> 4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <bits/stl_iterator_base_types.h> 4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <ext/cast.h> 4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <ext/type_traits.h> 4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L 4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <bits/move.h> 4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <bits/ptr_traits.h> 4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_GLIBCXX_BEGIN_NAMESPACE_VERSION 5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /** 5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * @brief A storage policy for use with _Pointer_adapter<> which yields a 5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * standard pointer. 5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * A _Storage_policy is required to provide 4 things: 5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 1) A get() API for returning the stored pointer value. 6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 2) An set() API for storing a pointer value. 6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 3) An element_type typedef to define the type this points to. 6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 4) An operator<() to support pointer comparison. 6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 5) An operator==() to support pointer comparison. 6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class _Std_pointer_impl 6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // the type this pointer points to. 7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef _Tp element_type; 7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // A method to fetch the pointer value as a standard T* value; 7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline _Tp* 7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert get() const 7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_value; } 7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // A method to set the pointer value, from a standard T* value; 7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert set(element_type* __arg) 8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _M_value = __arg; } 8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Comparison of pointers 8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator<(const _Std_pointer_impl& __rarg) const 8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (_M_value < __rarg._M_value); } 8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator==(const _Std_pointer_impl& __rarg) const 8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (_M_value == __rarg._M_value); } 9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert element_type* _M_value; 9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /** 9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * @brief A storage policy for use with _Pointer_adapter<> which stores 9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * the pointer's address as an offset value which is relative to 9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * its own address. 9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This is intended for pointers within shared memory regions which 10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * might be mapped at different addresses by different processes. 10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * For null pointers, a value of 1 is used. (0 is legitimate 10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * sometimes for nodes in circularly linked lists) This value was 10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * chosen as the least likely to generate an incorrect null, As 10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * there is no reason why any normal pointer would point 1 byte into 10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * its own pointer address. 10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class _Relative_pointer_impl 11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef _Tp element_type; 11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Tp* 11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert get() const 11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_diff == 1) 11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return 0; 11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else 12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return reinterpret_cast<_Tp*>(reinterpret_cast<_UIntPtrType>(this) 12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert + _M_diff); 12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert set(_Tp* __arg) 12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!__arg) 12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_diff = 1; 12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else 13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_diff = reinterpret_cast<_UIntPtrType>(__arg) 13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert - reinterpret_cast<_UIntPtrType>(this); 13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Comparison of pointers 13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator<(const _Relative_pointer_impl& __rarg) const 13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (reinterpret_cast<_UIntPtrType>(this->get()) 13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert < reinterpret_cast<_UIntPtrType>(__rarg.get())); } 13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator==(const _Relative_pointer_impl& __rarg) const 14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (reinterpret_cast<_UIntPtrType>(this->get()) 14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert == reinterpret_cast<_UIntPtrType>(__rarg.get())); } 14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef _GLIBCXX_USE_LONG_LONG 14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef __gnu_cxx::__conditional_type< 14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (sizeof(unsigned long) >= sizeof(void*)), 14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert unsigned long, unsigned long long>::__type _UIntPtrType; 15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else 15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef unsigned long _UIntPtrType; 15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _UIntPtrType _M_diff; 15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /** 15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Relative_pointer_impl needs a specialization for const T because of 15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * the casting done during pointer arithmetic. 15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class _Relative_pointer_impl<const _Tp> 16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef const _Tp element_type; 16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Tp* 16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert get() const 16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_diff == 1) 17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return 0; 17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else 17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return reinterpret_cast<const _Tp*> 17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (reinterpret_cast<_UIntPtrType>(this) + _M_diff); 17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert set(const _Tp* __arg) 17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!__arg) 18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_diff = 1; 18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else 18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_diff = reinterpret_cast<_UIntPtrType>(__arg) 18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert - reinterpret_cast<_UIntPtrType>(this); 18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Comparison of pointers 18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator<(const _Relative_pointer_impl& __rarg) const 18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (reinterpret_cast<_UIntPtrType>(this->get()) 19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert < reinterpret_cast<_UIntPtrType>(__rarg.get())); } 19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator==(const _Relative_pointer_impl& __rarg) const 19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (reinterpret_cast<_UIntPtrType>(this->get()) 19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert == reinterpret_cast<_UIntPtrType>(__rarg.get())); } 19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef _GLIBCXX_USE_LONG_LONG 19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef __gnu_cxx::__conditional_type< 20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (sizeof(unsigned long) >= sizeof(void*)), 20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert unsigned long, unsigned long long>::__type _UIntPtrType; 20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else 20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef unsigned long _UIntPtrType; 20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _UIntPtrType _M_diff; 20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /** 20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * The specialization on this type helps resolve the problem of 21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * reference to void, and eliminates the need to specialize 21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * _Pointer_adapter for cases of void*, const void*, and so on. 21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Invalid_type { }; 21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Reference_type 21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { typedef _Tp& reference; }; 21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Reference_type<void> 22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { typedef _Invalid_type& reference; }; 22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Reference_type<const void> 22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { typedef const _Invalid_type& reference; }; 22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Reference_type<volatile void> 22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { typedef volatile _Invalid_type& reference; }; 23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Reference_type<volatile const void> 23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { typedef const volatile _Invalid_type& reference; }; 23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /** 23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This structure accommodates the way in which 23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * std::iterator_traits<> is normally specialized for const T*, so 23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * that value_type is still T. 23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Unqualified_type 24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { typedef _Tp type; }; 24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Unqualified_type<const _Tp> 24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { typedef _Tp type; }; 24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /** 24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * The following provides an 'alternative pointer' that works with 25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * the containers when specified as the pointer typedef of the 25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * allocator. 25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * The pointer type used with the containers doesn't have to be this 25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * class, but it must support the implicit conversions, pointer 25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * arithmetic, comparison operators, etc. that are supported by this 25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * class, and avoid raising compile-time ambiguities. Because 25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * creating a working pointer can be challenging, this pointer 25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * template was designed to wrapper an easier storage policy type, 25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * so that it becomes reusable for creating other pointer types. 26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * A key point of this class is also that it allows container 26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * writers to 'assume' Allocator::pointer is a typedef for a normal 26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * pointer. This class supports most of the conventions of a true 26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * pointer, and can, for instance handle implicit conversion to 26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * const and base class pointer types. The only impositions on 26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * container writers to support extended pointers are: 1) use the 26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Allocator::pointer typedef appropriately for pointer types. 2) 26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * if you need pointer casting, use the __pointer_cast<> functions 26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * from ext/cast.h. This allows pointer cast operations to be 27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * overloaded as necessary by custom pointers. 27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Note: The const qualifier works with this pointer adapter as 27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * follows: 27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * _Tp* == _Pointer_adapter<_Std_pointer_impl<_Tp> >; 27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * const _Tp* == _Pointer_adapter<_Std_pointer_impl<const _Tp> >; 27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * _Tp* const == const _Pointer_adapter<_Std_pointer_impl<_Tp> >; 27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * const _Tp* const == const _Pointer_adapter<_Std_pointer_impl<const _Tp> >; 27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Storage_policy> 28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class _Pointer_adapter : public _Storage_policy 28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename _Storage_policy::element_type element_type; 28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // These are needed for iterator_traits 28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef std::random_access_iterator_tag iterator_category; 28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename _Unqualified_type<element_type>::type value_type; 28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef std::ptrdiff_t difference_type; 29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef _Pointer_adapter pointer; 29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename _Reference_type<element_type>::reference reference; 29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Reminder: 'const' methods mean that the method is valid when the 29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // pointer is immutable, and has nothing to do with whether the 29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 'pointee' is const. 29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Default Constructor (Convert from element_type*) 29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Pointer_adapter(element_type* __arg = 0) 29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _Storage_policy::set(__arg); } 30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Copy constructor from _Pointer_adapter of same type. 30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Pointer_adapter(const _Pointer_adapter& __arg) 30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _Storage_policy::set(__arg.get()); } 30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Convert from _Up* if conversion to element_type* is valid. 30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Up> 30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Pointer_adapter(_Up* __arg) 30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _Storage_policy::set(__arg); } 30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Conversion from another _Pointer_adapter if _Up if static cast is 31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // valid. 31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Up> 31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Pointer_adapter(const _Pointer_adapter<_Up>& __arg) 31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _Storage_policy::set(__arg.get()); } 31511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Destructor 31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ~_Pointer_adapter() { } 31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Assignment operator 32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Pointer_adapter& 32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(const _Pointer_adapter& __arg) 32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Storage_policy::set(__arg.get()); 32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Up> 32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Pointer_adapter& 32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(const _Pointer_adapter<_Up>& __arg) 33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Storage_policy::set(__arg.get()); 33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Up> 33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Pointer_adapter& 33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(_Up* __arg) 33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Storage_policy::set(__arg); 34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Operator*, returns element_type& 34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline reference 34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator*() const 34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return *(_Storage_policy::get()); } 34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Operator->, returns element_type* 34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline element_type* 35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator->() const 35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _Storage_policy::get(); } 35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Operator[], returns a element_type& to the item at that loc. 35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline reference 35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator[](std::ptrdiff_t __index) const 35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _Storage_policy::get()[__index]; } 35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // To allow implicit conversion to "bool", for "if (ptr)..." 35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef element_type*(_Pointer_adapter::*__unspecified_bool_type)() const; 36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator __unspecified_bool_type() const 36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _Storage_policy::get() == 0 ? 0 : 36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert &_Pointer_adapter::operator->; 36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 36811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // ! operator (for: if (!ptr)...) 37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator!() const 37211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (_Storage_policy::get() == 0); } 37311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Pointer differences 37511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline friend std::ptrdiff_t 37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator-(const _Pointer_adapter& __lhs, element_type* __rhs) 37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (__lhs.get() - __rhs); } 37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline friend std::ptrdiff_t 38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator-(element_type* __lhs, const _Pointer_adapter& __rhs) 38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (__lhs - __rhs.get()); } 38211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Up> 38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline friend std::ptrdiff_t 38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator-(const _Pointer_adapter& __lhs, _Up* __rhs) 38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (__lhs.get() - __rhs); } 38711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 38811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Up> 38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline friend std::ptrdiff_t 39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator-(_Up* __lhs, const _Pointer_adapter& __rhs) 39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (__lhs - __rhs.get()); } 39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 39311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Up> 39411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline std::ptrdiff_t 39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator-(const _Pointer_adapter<_Up>& __rhs) const 39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (_Storage_policy::get() - __rhs.get()); } 39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Pointer math 39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Note: There is a reason for all this overloading based on different 40011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // integer types. In some libstdc++-v3 test cases, a templated 40111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // operator+ is declared which can match any types. This operator 40211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // tends to "steal" the recognition of _Pointer_adapter's own operator+ 40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // unless the integer type matches perfectly. 40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define _CXX_POINTER_ARITH_OPERATOR_SET(INT_TYPE) \ 40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline friend _Pointer_adapter \ 40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator+(const _Pointer_adapter& __lhs, INT_TYPE __offset) \ 40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _Pointer_adapter(__lhs.get() + __offset); } \ 40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert\ 41011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline friend _Pointer_adapter \ 41111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator+(INT_TYPE __offset, const _Pointer_adapter& __rhs) \ 41211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _Pointer_adapter(__rhs.get() + __offset); } \ 41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert\ 41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline friend _Pointer_adapter \ 41511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator-(const _Pointer_adapter& __lhs, INT_TYPE __offset) \ 41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _Pointer_adapter(__lhs.get() - __offset); } \ 41711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert\ 41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline _Pointer_adapter& \ 41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator+=(INT_TYPE __offset) \ 42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { \ 42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Storage_policy::set(_Storage_policy::get() + __offset); \ 42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; \ 42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } \ 42411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert\ 42511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline _Pointer_adapter& \ 42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator-=(INT_TYPE __offset) \ 42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { \ 42811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Storage_policy::set(_Storage_policy::get() - __offset); \ 42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; \ 43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } \ 43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// END of _CXX_POINTER_ARITH_OPERATOR_SET macro 43211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 43311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Expand into the various pointer arithmetic operators needed. 43411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CXX_POINTER_ARITH_OPERATOR_SET(short); 43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CXX_POINTER_ARITH_OPERATOR_SET(unsigned short); 43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CXX_POINTER_ARITH_OPERATOR_SET(int); 43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CXX_POINTER_ARITH_OPERATOR_SET(unsigned int); 43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CXX_POINTER_ARITH_OPERATOR_SET(long); 43911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CXX_POINTER_ARITH_OPERATOR_SET(unsigned long); 44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Mathematical Manipulators 44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline _Pointer_adapter& 44311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator++() 44411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Storage_policy::set(_Storage_policy::get() + 1); 44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline _Pointer_adapter 45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator++(int) 45111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Pointer_adapter tmp(*this); 45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Storage_policy::set(_Storage_policy::get() + 1); 45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return tmp; 45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 45611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 45711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline _Pointer_adapter& 45811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator--() 45911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 46011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Storage_policy::set(_Storage_policy::get() - 1); 46111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 46211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 46311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 46411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline _Pointer_adapter 46511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator--(int) 46611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 46711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Pointer_adapter tmp(*this); 46811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Storage_policy::set(_Storage_policy::get() - 1); 46911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return tmp; 47011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 47111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 47211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; // class _Pointer_adapter 47311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 47411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 47511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(OPERATOR) \ 47611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Tp2> \ 47711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool \ 47811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, _Tp2 __rhs) \ 47911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __lhs.get() OPERATOR __rhs; } \ 48011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert\ 48111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Tp2> \ 48211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool \ 48311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator OPERATOR(_Tp1 __lhs, const _Pointer_adapter<_Tp2>& __rhs) \ 48411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __lhs OPERATOR __rhs.get(); } \ 48511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert\ 48611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Tp2> \ 48711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool \ 48811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, \ 48911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Pointer_adapter<_Tp2>& __rhs) \ 49011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __lhs.get() OPERATOR __rhs.get(); } \ 49111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert\ 49211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// End GCC_CXX_POINTER_COMPARISON_OPERATION_SET Macro 49311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 49411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Expand into the various comparison operators needed. 49511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(==) 49611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(!=) 49711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<) 49811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<=) 49911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>) 50011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>=) 50111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 50211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // These are here for expressions like "ptr == 0", "ptr != 0" 50311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 50411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 50511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator==(const _Pointer_adapter<_Tp>& __lhs, int __rhs) 50611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __lhs.get() == reinterpret_cast<void*>(__rhs); } 50711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 50811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 50911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 51011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator==(int __lhs, const _Pointer_adapter<_Tp>& __rhs) 51111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __rhs.get() == reinterpret_cast<void*>(__lhs); } 51211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 51311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 51411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 51511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator!=(const _Pointer_adapter<_Tp>& __lhs, int __rhs) 51611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __lhs.get() != reinterpret_cast<void*>(__rhs); } 51711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 51811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 51911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 52011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator!=(int __lhs, const _Pointer_adapter<_Tp>& __rhs) 52111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __rhs.get() != reinterpret_cast<void*>(__lhs); } 52211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 52311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /** 52411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Comparison operators for _Pointer_adapter defer to the base class' 52511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * comparison operators, when possible. 52611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 52711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 52811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 52911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator==(const _Pointer_adapter<_Tp>& __lhs, 53011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Pointer_adapter<_Tp>& __rhs) 53111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __lhs._Tp::operator==(__rhs); } 53211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 53311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 53411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 53511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator<=(const _Pointer_adapter<_Tp>& __lhs, 53611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Pointer_adapter<_Tp>& __rhs) 53711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs); } 53811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 53911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 54011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 54111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator!=(const _Pointer_adapter<_Tp>& __lhs, 54211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Pointer_adapter<_Tp>& __rhs) 54311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return !(__lhs._Tp::operator==(__rhs)); } 54411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 54511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 54611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 54711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator>(const _Pointer_adapter<_Tp>& __lhs, 54811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Pointer_adapter<_Tp>& __rhs) 54911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return !(__lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs)); } 55011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 55111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 55211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 55311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator>=(const _Pointer_adapter<_Tp>& __lhs, 55411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Pointer_adapter<_Tp>& __rhs) 55511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return !(__lhs._Tp::operator<(__rhs)); } 55611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 55711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _StoreT> 55811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline std::basic_ostream<_CharT, _Traits>& 55911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator<<(std::basic_ostream<_CharT, _Traits>& __os, 56011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Pointer_adapter<_StoreT>& __p) 56111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (__os << __p.get()); } 56211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 56311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_GLIBCXX_END_NAMESPACE_VERSION 56411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} // namespace 56511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 56611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L 56711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace std _GLIBCXX_VISIBILITY(default) 56811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 56911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_GLIBCXX_BEGIN_NAMESPACE_VERSION 57011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 57111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Storage_policy> 57211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct pointer_traits<__gnu_cxx::_Pointer_adapter<_Storage_policy>> 57311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 57411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// The pointer type 57511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef __gnu_cxx::_Pointer_adapter<_Storage_policy> pointer; 57611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// The type pointed to 57711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename pointer::element_type element_type; 57811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// Type used to represent the difference between two pointers 57911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename pointer::difference_type difference_type; 58011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 58111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Up> 58211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using rebind = typename __gnu_cxx::_Pointer_adapter< 58311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename pointer_traits<_Storage_policy>::template rebind<_Up>>; 58411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 58511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static pointer pointer_to(typename pointer::reference __r) noexcept 58611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return pointer(std::addressof(__r)); } 58711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 58811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 58911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_GLIBCXX_END_NAMESPACE_VERSION 59011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} // namespace 59111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 59211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 59311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // _POINTER_H 594