A storage policy for use with _Pointer_adapter<> which yields a standard pointer.
A _Storage_policy is required to provide 4 things: 1) A get() API for returning the stored pointer value. 2) An set() API for storing a pointer value. 3) An element_type typedef to define the type this points to. 4) An operator<() to support pointer comparison. 5) An operator==() to support pointer comparison.
A storage policy for use with _Pointer_adapter<> which stores the pointer's address as an offset value which is relative to its own address.
This is intended for pointers within shared memory regions which might be mapped at different addresses by different processes. For null pointers, a value of 1 is used. (0 is legitimate sometimes for nodes in circularly linked lists) This value was chosen as the least likely to generate an incorrect null, As there is no reason why any normal pointer would point 1 byte into its own pointer address.
Relative_pointer_impl needs a specialization for const T because of the casting done during pointer arithmetic.
The specialization on this type helps resolve the problem of reference to void, and eliminates the need to specialize _Pointer_adapter for cases of void*, const void*, and so on.
This structure accommodates the way in which std::iterator_traits<> is normally specialized for const T*, so that value_type is still T.
The following provides an 'alternative pointer' that works with the containers when specified as the pointer typedef of the allocator.
The pointer type used with the containers doesn't have to be this class, but it must support the implicit conversions, pointer arithmetic, comparison operators, etc. that are supported by this class, and avoid raising compile-time ambiguities. Because creating a working pointer can be challenging, this pointer template was designed to wrapper an easier storage policy type, so that it becomes reusable for creating other pointer types.
A key point of this class is also that it allows container writers to 'assume' Allocator::pointer is a typedef for a normal pointer. This class supports most of the conventions of a true pointer, and can, for instance handle implicit conversion to const and base class pointer types. The only impositions on container writers to support extended pointers are: 1) use the Allocator::pointer typedef appropriately for pointer types. 2) if you need pointer casting, use the __pointer_cast<> functions from ext/cast.h. This allows pointer cast operations to be overloaded as necessary by custom pointers.
_Tp* == _Pointer_adapter<_Std_pointer_impl<_Tp> >; const _Tp* == _Pointer_adapter<_Std_pointer_impl<const _Tp> >; _Tp* const == const _Pointer_adapter<_Std_pointer_impl<_Tp> >; const _Tp* const == const _Pointer_adapter<_Std_pointer_impl<const _Tp> >;
Comparison operators for _Pointer_adapter defer to the base class' comparison operators, when possible.
52 _GLIBCXX_BEGIN_NAMESPACE_VERSION
65 template<
typename _Tp>
66 class _Std_pointer_impl
70 typedef _Tp element_type;
79 set(element_type* __arg)
84 operator<(
const _Std_pointer_impl& __rarg)
const
85 {
return (_M_value < __rarg._M_value); }
88 operator==(
const _Std_pointer_impl& __rarg)
const
89 {
return (_M_value == __rarg._M_value); }
92 element_type* _M_value;
108 template<
typename _Tp>
109 class _Relative_pointer_impl
112 typedef _Tp element_type;
120 return reinterpret_cast<_Tp*
>(
reinterpret_cast<_UIntPtrType
>(
this)
130 _M_diff =
reinterpret_cast<_UIntPtrType
>(__arg)
131 - reinterpret_cast<_UIntPtrType>(
this);
136 operator<(
const _Relative_pointer_impl& __rarg)
const
137 {
return (reinterpret_cast<_UIntPtrType>(this->
get())
138 < reinterpret_cast<_UIntPtrType>(__rarg.get())); }
141 operator==(
const _Relative_pointer_impl& __rarg)
const
142 {
return (reinterpret_cast<_UIntPtrType>(this->
get())
143 == reinterpret_cast<_UIntPtrType>(__rarg.get())); }
146 #ifdef _GLIBCXX_USE_LONG_LONG
147 typedef __gnu_cxx::__conditional_type<
148 (
sizeof(
unsigned long) >=
sizeof(
void*)),
149 unsigned long,
unsigned long long>::__type _UIntPtrType;
151 typedef unsigned long _UIntPtrType;
153 _UIntPtrType _M_diff;
160 template<
typename _Tp>
161 class _Relative_pointer_impl<const _Tp>
164 typedef const _Tp element_type;
172 return reinterpret_cast<const _Tp*
>
173 (
reinterpret_cast<_UIntPtrType
>(
this) + _M_diff);
177 set(
const _Tp* __arg)
182 _M_diff =
reinterpret_cast<_UIntPtrType
>(__arg)
183 - reinterpret_cast<_UIntPtrType>(
this);
188 operator<(
const _Relative_pointer_impl& __rarg)
const
189 {
return (reinterpret_cast<_UIntPtrType>(this->
get())
190 < reinterpret_cast<_UIntPtrType>(__rarg.get())); }
193 operator==(
const _Relative_pointer_impl& __rarg)
const
194 {
return (reinterpret_cast<_UIntPtrType>(this->
get())
195 == reinterpret_cast<_UIntPtrType>(__rarg.get())); }
198 #ifdef _GLIBCXX_USE_LONG_LONG
199 typedef __gnu_cxx::__conditional_type<
200 (
sizeof(
unsigned long) >=
sizeof(
void*)),
201 unsigned long,
unsigned long long>::__type _UIntPtrType;
203 typedef unsigned long _UIntPtrType;
205 _UIntPtrType _M_diff;
213 struct _Invalid_type { };
215 template<
typename _Tp>
216 struct _Reference_type
217 {
typedef _Tp& reference; };
220 struct _Reference_type<void>
221 {
typedef _Invalid_type& reference; };
224 struct _Reference_type<const void>
225 {
typedef const _Invalid_type& reference; };
228 struct _Reference_type<volatile void>
229 {
typedef volatile _Invalid_type& reference; };
232 struct _Reference_type<volatile const void>
233 {
typedef const volatile _Invalid_type& reference; };
240 template<
typename _Tp>
241 struct _Unqualified_type
242 {
typedef _Tp type; };
244 template<
typename _Tp>
245 struct _Unqualified_type<const _Tp>
246 {
typedef _Tp type; };
280 template<
typename _Storage_policy>
281 class _Pointer_adapter :
public _Storage_policy
284 typedef typename _Storage_policy::element_type element_type;
287 typedef std::random_access_iterator_tag iterator_category;
288 typedef typename _Unqualified_type<element_type>::type value_type;
290 typedef _Pointer_adapter pointer;
291 typedef typename _Reference_type<element_type>::reference reference;
298 _Pointer_adapter(element_type* __arg = 0)
299 { _Storage_policy::set(__arg); }
302 _Pointer_adapter(
const _Pointer_adapter& __arg)
303 { _Storage_policy::set(__arg.get()); }
306 template<
typename _Up>
307 _Pointer_adapter(_Up* __arg)
308 { _Storage_policy::set(__arg); }
312 template<
typename _Up>
313 _Pointer_adapter(
const _Pointer_adapter<_Up>& __arg)
314 { _Storage_policy::set(__arg.get()); }
317 ~_Pointer_adapter() { }
321 operator=(
const _Pointer_adapter& __arg)
323 _Storage_policy::set(__arg.get());
327 template<
typename _Up>
329 operator=(
const _Pointer_adapter<_Up>& __arg)
331 _Storage_policy::set(__arg.get());
335 template<
typename _Up>
337 operator=(_Up* __arg)
339 _Storage_policy::set(__arg);
346 {
return *(_Storage_policy::get()); }
351 {
return _Storage_policy::get(); }
356 {
return _Storage_policy::get()[__index]; }
360 typedef element_type*(_Pointer_adapter::*__unspecified_bool_type)()
const;
363 operator __unspecified_bool_type()
const
365 return _Storage_policy::get() == 0 ? 0 :
366 &_Pointer_adapter::operator->;
372 {
return (_Storage_policy::get() == 0); }
376 operator-(
const _Pointer_adapter& __lhs, element_type* __rhs)
377 {
return (__lhs.get() - __rhs); }
380 operator-(element_type* __lhs,
const _Pointer_adapter& __rhs)
381 {
return (__lhs - __rhs.get()); }
383 template<
typename _Up>
385 operator-(
const _Pointer_adapter& __lhs, _Up* __rhs)
386 {
return (__lhs.get() - __rhs); }
388 template<
typename _Up>
390 operator-(_Up* __lhs,
const _Pointer_adapter& __rhs)
391 {
return (__lhs - __rhs.get()); }
393 template<
typename _Up>
395 operator-(
const _Pointer_adapter<_Up>& __rhs)
const
396 {
return (_Storage_policy::get() - __rhs.get()); }
405 #define _CXX_POINTER_ARITH_OPERATOR_SET(INT_TYPE) \
406 inline friend _Pointer_adapter \
407 operator+(const _Pointer_adapter& __lhs, INT_TYPE __offset) \
408 { return _Pointer_adapter(__lhs.get() + __offset); } \
410 inline friend _Pointer_adapter \
411 operator+(INT_TYPE __offset, const _Pointer_adapter& __rhs) \
412 { return _Pointer_adapter(__rhs.get() + __offset); } \
414 inline friend _Pointer_adapter \
415 operator-(const _Pointer_adapter& __lhs, INT_TYPE __offset) \
416 { return _Pointer_adapter(__lhs.get() - __offset); } \
418 inline _Pointer_adapter& \
419 operator+=(INT_TYPE __offset) \
421 _Storage_policy::set(_Storage_policy::get() + __offset); \
425 inline _Pointer_adapter& \
426 operator-=(INT_TYPE __offset) \
428 _Storage_policy::set(_Storage_policy::get() - __offset); \
431 // END of _CXX_POINTER_ARITH_OPERATOR_SET macro
442 inline _Pointer_adapter&
445 _Storage_policy::set(_Storage_policy::get() + 1);
449 inline _Pointer_adapter
452 _Pointer_adapter tmp(*
this);
453 _Storage_policy::set(_Storage_policy::get() + 1);
457 inline _Pointer_adapter&
460 _Storage_policy::set(_Storage_policy::get() - 1);
464 inline _Pointer_adapter
467 _Pointer_adapter tmp(*
this);
468 _Storage_policy::set(_Storage_policy::get() - 1);
475 #define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(OPERATOR) \
476 template<typename _Tp1, typename _Tp2> \
478 operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, _Tp2 __rhs) \
479 { return __lhs.get() OPERATOR __rhs; } \
481 template<typename _Tp1, typename _Tp2> \
483 operator OPERATOR(_Tp1 __lhs, const _Pointer_adapter<_Tp2>& __rhs) \
484 { return __lhs OPERATOR __rhs.get(); } \
486 template<typename _Tp1, typename _Tp2> \
488 operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, \
489 const _Pointer_adapter<_Tp2>& __rhs) \
490 { return __lhs.get() OPERATOR __rhs.get(); } \
492 // End GCC_CXX_POINTER_COMPARISON_OPERATION_SET Macro
503 template<typename _Tp>
505 operator==(const _Pointer_adapter<_Tp>& __lhs,
int __rhs)
506 {
return __lhs.get() ==
reinterpret_cast<void*
>(__rhs); }
508 template<
typename _Tp>
510 operator==(
int __lhs,
const _Pointer_adapter<_Tp>& __rhs)
511 {
return __rhs.get() ==
reinterpret_cast<void*
>(__lhs); }
513 template<
typename _Tp>
515 operator!=(
const _Pointer_adapter<_Tp>& __lhs,
int __rhs)
516 {
return __lhs.get() !=
reinterpret_cast<void*
>(__rhs); }
518 template<
typename _Tp>
520 operator!=(
int __lhs,
const _Pointer_adapter<_Tp>& __rhs)
521 {
return __rhs.get() !=
reinterpret_cast<void*
>(__lhs); }
527 template<
typename _Tp>
529 operator==(
const _Pointer_adapter<_Tp>& __lhs,
530 const _Pointer_adapter<_Tp>& __rhs)
531 {
return __lhs._Tp::operator==(__rhs); }
533 template<
typename _Tp>
535 operator<=(const _Pointer_adapter<_Tp>& __lhs,
536 const _Pointer_adapter<_Tp>& __rhs)
537 {
return __lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs); }
539 template<
typename _Tp>
541 operator!=(
const _Pointer_adapter<_Tp>& __lhs,
542 const _Pointer_adapter<_Tp>& __rhs)
543 {
return !(__lhs._Tp::operator==(__rhs)); }
545 template<
typename _Tp>
547 operator>(
const _Pointer_adapter<_Tp>& __lhs,
548 const _Pointer_adapter<_Tp>& __rhs)
549 {
return !(__lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs)); }
551 template<
typename _Tp>
553 operator>=(
const _Pointer_adapter<_Tp>& __lhs,
554 const _Pointer_adapter<_Tp>& __rhs)
555 {
return !(__lhs._Tp::operator<(__rhs)); }
557 template<
typename _CharT,
typename _Traits,
typename _StoreT>
558 inline std::basic_ostream<_CharT, _Traits>&
559 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
560 const _Pointer_adapter<_StoreT>& __p)
561 {
return (__os << __p.get()); }
563 _GLIBCXX_END_NAMESPACE_VERSION
bool operator>=(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:644
bool operator==(const exception_ptr &, const exception_ptr &) _GLIBCXX_USE_NOEXCEPT __attribute__((__pure__))
bool operator<(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:548
bool operator>(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:612
#define _CXX_POINTER_ARITH_OPERATOR_SET(INT_TYPE)
_Safe_iterator< _IteratorL, _Sequence >::difference_type operator-(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:680
bool operator!=(const exception_ptr &, const exception_ptr &) _GLIBCXX_USE_NOEXCEPT __attribute__((__pure__))
__PTRDIFF_TYPE__ ptrdiff_t
Definition: stddef.h:147
#define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(OPERATOR)