STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Macros | Functions
pointer.h File Reference
#include <iosfwd>
#include <bits/stl_iterator_base_types.h>
#include <ext/cast.h>
#include <ext/type_traits.h>

Go to the source code of this file.

Macros

#define _CXX_POINTER_ARITH_OPERATOR_SET(INT_TYPE)
 
#define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(OPERATOR)
 

Functions

namespace __gnu_cxx _GLIBCXX_VISIBILITY (default)
 

Detailed Description

This file is a GNU extension to the Standard C++ Library.

Author
Bob Walters

Provides reusable _Pointer_adapter for assisting in the development of custom pointer types that can be used with the standard containers via the allocator::pointer and allocator::const_pointer typedefs.

Macro Definition Documentation

#define _CXX_POINTER_ARITH_OPERATOR_SET (   INT_TYPE)
Value:
inline friend _Pointer_adapter \
operator+(const _Pointer_adapter& __lhs, INT_TYPE __offset) \
{ return _Pointer_adapter(__lhs.get() + __offset); } \
\
inline friend _Pointer_adapter \
operator+(INT_TYPE __offset, const _Pointer_adapter& __rhs) \
{ return _Pointer_adapter(__rhs.get() + __offset); } \
\
inline friend _Pointer_adapter \
operator-(const _Pointer_adapter& __lhs, INT_TYPE __offset) \
{ return _Pointer_adapter(__lhs.get() - __offset); } \
\
inline _Pointer_adapter& \
operator+=(INT_TYPE __offset) \
{ \
_Storage_policy::set(_Storage_policy::get() + __offset); \
return *this; \
} \
\
inline _Pointer_adapter& \
operator-=(INT_TYPE __offset) \
{ \
_Storage_policy::set(_Storage_policy::get() - __offset); \
return *this; \
} \
_Safe_iterator< _Iterator, _Sequence > operator+(typename _Safe_iterator< _Iterator, _Sequence >::difference_type __n, const _Safe_iterator< _Iterator, _Sequence > &__i)
Definition: safe_iterator.h:712
return(unsigned int) __res
_Safe_iterator< _IteratorL, _Sequence >::difference_type operator-(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:680
#define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET (   OPERATOR)
Value:
template<typename _Tp1, typename _Tp2> \
inline bool \
operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, _Tp2 __rhs) \
{ return __lhs.get() OPERATOR __rhs; } \
\
template<typename _Tp1, typename _Tp2> \
inline bool \
operator OPERATOR(_Tp1 __lhs, const _Pointer_adapter<_Tp2>& __rhs) \
{ return __lhs OPERATOR __rhs.get(); } \
\
template<typename _Tp1, typename _Tp2> \
inline bool \
operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, \
const _Pointer_adapter<_Tp2>& __rhs) \
{ return __lhs.get() OPERATOR __rhs.get(); } \
\

Function Documentation

namespace __gnu_cxx _GLIBCXX_VISIBILITY ( default  )

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.

Note: The const qualifier works with this pointer adapter as follows:

_Tp* == _Pointer_adapter<_Std_pointer_impl<_Tp> >; const _Tp* == _Pointer_adapter<_Std_pointer_impl<const _Tp> >; _Tp* const == const _Pointer_adapter<_Std_pointer_impl<_Tp> >; const _Tp* const == const _Pointer_adapter<_Std_pointer_impl<const _Tp> >;

Comparison operators for _Pointer_adapter defer to the base class' comparison operators, when possible.

51 {
52 _GLIBCXX_BEGIN_NAMESPACE_VERSION
53 
65  template<typename _Tp>
66  class _Std_pointer_impl
67  {
68  public:
69  // the type this pointer points to.
70  typedef _Tp element_type;
71 
72  // A method to fetch the pointer value as a standard T* value;
73  inline _Tp*
74  get() const
75  { return _M_value; }
76 
77  // A method to set the pointer value, from a standard T* value;
78  inline void
79  set(element_type* __arg)
80  { _M_value = __arg; }
81 
82  // Comparison of pointers
83  inline bool
84  operator<(const _Std_pointer_impl& __rarg) const
85  { return (_M_value < __rarg._M_value); }
86 
87  inline bool
88  operator==(const _Std_pointer_impl& __rarg) const
89  { return (_M_value == __rarg._M_value); }
90 
91  private:
92  element_type* _M_value;
93  };
94 
108  template<typename _Tp>
109  class _Relative_pointer_impl
110  {
111  public:
112  typedef _Tp element_type;
113 
114  _Tp*
115  get() const
116  {
117  if (_M_diff == 1)
118  return 0;
119  else
120  return reinterpret_cast<_Tp*>(reinterpret_cast<_UIntPtrType>(this)
121  + _M_diff);
122  }
123 
124  void
125  set(_Tp* __arg)
126  {
127  if (!__arg)
128  _M_diff = 1;
129  else
130  _M_diff = reinterpret_cast<_UIntPtrType>(__arg)
131  - reinterpret_cast<_UIntPtrType>(this);
132  }
133 
134  // Comparison of pointers
135  inline bool
136  operator<(const _Relative_pointer_impl& __rarg) const
137  { return (reinterpret_cast<_UIntPtrType>(this->get())
138  < reinterpret_cast<_UIntPtrType>(__rarg.get())); }
139 
140  inline bool
141  operator==(const _Relative_pointer_impl& __rarg) const
142  { return (reinterpret_cast<_UIntPtrType>(this->get())
143  == reinterpret_cast<_UIntPtrType>(__rarg.get())); }
144 
145  private:
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;
150 #else
151  typedef unsigned long _UIntPtrType;
152 #endif
153  _UIntPtrType _M_diff;
154  };
155 
160  template<typename _Tp>
161  class _Relative_pointer_impl<const _Tp>
162  {
163  public:
164  typedef const _Tp element_type;
165 
166  const _Tp*
167  get() const
168  {
169  if (_M_diff == 1)
170  return 0;
171  else
172  return reinterpret_cast<const _Tp*>
173  (reinterpret_cast<_UIntPtrType>(this) + _M_diff);
174  }
175 
176  void
177  set(const _Tp* __arg)
178  {
179  if (!__arg)
180  _M_diff = 1;
181  else
182  _M_diff = reinterpret_cast<_UIntPtrType>(__arg)
183  - reinterpret_cast<_UIntPtrType>(this);
184  }
185 
186  // Comparison of pointers
187  inline bool
188  operator<(const _Relative_pointer_impl& __rarg) const
189  { return (reinterpret_cast<_UIntPtrType>(this->get())
190  < reinterpret_cast<_UIntPtrType>(__rarg.get())); }
191 
192  inline bool
193  operator==(const _Relative_pointer_impl& __rarg) const
194  { return (reinterpret_cast<_UIntPtrType>(this->get())
195  == reinterpret_cast<_UIntPtrType>(__rarg.get())); }
196 
197  private:
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;
202 #else
203  typedef unsigned long _UIntPtrType;
204 #endif
205  _UIntPtrType _M_diff;
206  };
207 
213  struct _Invalid_type { };
214 
215  template<typename _Tp>
216  struct _Reference_type
217  { typedef _Tp& reference; };
218 
219  template<>
220  struct _Reference_type<void>
221  { typedef _Invalid_type& reference; };
222 
223  template<>
224  struct _Reference_type<const void>
225  { typedef const _Invalid_type& reference; };
226 
227  template<>
228  struct _Reference_type<volatile void>
229  { typedef volatile _Invalid_type& reference; };
230 
231  template<>
232  struct _Reference_type<volatile const void>
233  { typedef const volatile _Invalid_type& reference; };
234 
240  template<typename _Tp>
241  struct _Unqualified_type
242  { typedef _Tp type; };
243 
244  template<typename _Tp>
245  struct _Unqualified_type<const _Tp>
246  { typedef _Tp type; };
247 
280  template<typename _Storage_policy>
281  class _Pointer_adapter : public _Storage_policy
282  {
283  public:
284  typedef typename _Storage_policy::element_type element_type;
285 
286  // These are needed for iterator_traits
287  typedef std::random_access_iterator_tag iterator_category;
288  typedef typename _Unqualified_type<element_type>::type value_type;
289  typedef std::ptrdiff_t difference_type;
290  typedef _Pointer_adapter pointer;
291  typedef typename _Reference_type<element_type>::reference reference;
292 
293  // Reminder: 'const' methods mean that the method is valid when the
294  // pointer is immutable, and has nothing to do with whether the
295  // 'pointee' is const.
296 
297  // Default Constructor (Convert from element_type*)
298  _Pointer_adapter(element_type* __arg = 0)
299  { _Storage_policy::set(__arg); }
300 
301  // Copy constructor from _Pointer_adapter of same type.
302  _Pointer_adapter(const _Pointer_adapter& __arg)
303  { _Storage_policy::set(__arg.get()); }
304 
305  // Convert from _Up* if conversion to element_type* is valid.
306  template<typename _Up>
307  _Pointer_adapter(_Up* __arg)
308  { _Storage_policy::set(__arg); }
309 
310  // Conversion from another _Pointer_adapter if _Up if static cast is
311  // valid.
312  template<typename _Up>
313  _Pointer_adapter(const _Pointer_adapter<_Up>& __arg)
314  { _Storage_policy::set(__arg.get()); }
315 
316  // Destructor
317  ~_Pointer_adapter() { }
318 
319  // Assignment operator
320  _Pointer_adapter&
321  operator=(const _Pointer_adapter& __arg)
322  {
323  _Storage_policy::set(__arg.get());
324  return *this;
325  }
326 
327  template<typename _Up>
328  _Pointer_adapter&
329  operator=(const _Pointer_adapter<_Up>& __arg)
330  {
331  _Storage_policy::set(__arg.get());
332  return *this;
333  }
334 
335  template<typename _Up>
336  _Pointer_adapter&
337  operator=(_Up* __arg)
338  {
339  _Storage_policy::set(__arg);
340  return *this;
341  }
342 
343  // Operator*, returns element_type&
344  inline reference
345  operator*() const
346  { return *(_Storage_policy::get()); }
347 
348  // Operator->, returns element_type*
349  inline element_type*
350  operator->() const
351  { return _Storage_policy::get(); }
352 
353  // Operator[], returns a element_type& to the item at that loc.
354  inline reference
355  operator[](std::ptrdiff_t __index) const
356  { return _Storage_policy::get()[__index]; }
357 
358  // To allow implicit conversion to "bool", for "if (ptr)..."
359  private:
360  typedef element_type*(_Pointer_adapter::*__unspecified_bool_type)() const;
361 
362  public:
363  operator __unspecified_bool_type() const
364  {
365  return _Storage_policy::get() == 0 ? 0 :
366  &_Pointer_adapter::operator->;
367  }
368 
369  // ! operator (for: if (!ptr)...)
370  inline bool
371  operator!() const
372  { return (_Storage_policy::get() == 0); }
373 
374  // Pointer differences
375  inline friend std::ptrdiff_t
376  operator-(const _Pointer_adapter& __lhs, element_type* __rhs)
377  { return (__lhs.get() - __rhs); }
378 
379  inline friend std::ptrdiff_t
380  operator-(element_type* __lhs, const _Pointer_adapter& __rhs)
381  { return (__lhs - __rhs.get()); }
382 
383  template<typename _Up>
384  inline friend std::ptrdiff_t
385  operator-(const _Pointer_adapter& __lhs, _Up* __rhs)
386  { return (__lhs.get() - __rhs); }
387 
388  template<typename _Up>
389  inline friend std::ptrdiff_t
390  operator-(_Up* __lhs, const _Pointer_adapter& __rhs)
391  { return (__lhs - __rhs.get()); }
392 
393  template<typename _Up>
394  inline std::ptrdiff_t
395  operator-(const _Pointer_adapter<_Up>& __rhs) const
396  { return (_Storage_policy::get() - __rhs.get()); }
397 
398  // Pointer math
399  // Note: There is a reason for all this overloading based on different
400  // integer types. In some libstdc++-v3 test cases, a templated
401  // operator+ is declared which can match any types. This operator
402  // tends to "steal" the recognition of _Pointer_adapter's own operator+
403  // unless the integer type matches perfectly.
404 
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); } \
409 \
410  inline friend _Pointer_adapter \
411  operator+(INT_TYPE __offset, const _Pointer_adapter& __rhs) \
412  { return _Pointer_adapter(__rhs.get() + __offset); } \
413 \
414  inline friend _Pointer_adapter \
415  operator-(const _Pointer_adapter& __lhs, INT_TYPE __offset) \
416  { return _Pointer_adapter(__lhs.get() - __offset); } \
417 \
418  inline _Pointer_adapter& \
419  operator+=(INT_TYPE __offset) \
420  { \
421  _Storage_policy::set(_Storage_policy::get() + __offset); \
422  return *this; \
423  } \
424 \
425  inline _Pointer_adapter& \
426  operator-=(INT_TYPE __offset) \
427  { \
428  _Storage_policy::set(_Storage_policy::get() - __offset); \
429  return *this; \
430  } \
431 // END of _CXX_POINTER_ARITH_OPERATOR_SET macro
432 
433  // Expand into the various pointer arithmetic operators needed.
435  _CXX_POINTER_ARITH_OPERATOR_SET(unsigned short);
437  _CXX_POINTER_ARITH_OPERATOR_SET(unsigned int);
439  _CXX_POINTER_ARITH_OPERATOR_SET(unsigned long);
440 
441  // Mathematical Manipulators
442  inline _Pointer_adapter&
443  operator++()
444  {
445  _Storage_policy::set(_Storage_policy::get() + 1);
446  return *this;
447  }
448 
449  inline _Pointer_adapter
450  operator++(int)
451  {
452  _Pointer_adapter tmp(*this);
453  _Storage_policy::set(_Storage_policy::get() + 1);
454  return tmp;
455  }
456 
457  inline _Pointer_adapter&
458  operator--()
459  {
460  _Storage_policy::set(_Storage_policy::get() - 1);
461  return *this;
462  }
463 
464  inline _Pointer_adapter
465  operator--(int)
466  {
467  _Pointer_adapter tmp(*this);
468  _Storage_policy::set(_Storage_policy::get() - 1);
469  return tmp;
470  }
471 
472  }; // class _Pointer_adapter
473 
474 
475 #define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(OPERATOR) \
476  template<typename _Tp1, typename _Tp2> \
477  inline bool \
478  operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, _Tp2 __rhs) \
479  { return __lhs.get() OPERATOR __rhs; } \
480 \
481  template<typename _Tp1, typename _Tp2> \
482  inline bool \
483  operator OPERATOR(_Tp1 __lhs, const _Pointer_adapter<_Tp2>& __rhs) \
484  { return __lhs OPERATOR __rhs.get(); } \
485 \
486  template<typename _Tp1, typename _Tp2> \
487  inline bool \
488  operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, \
489  const _Pointer_adapter<_Tp2>& __rhs) \
490  { return __lhs.get() OPERATOR __rhs.get(); } \
491 \
492 // End GCC_CXX_POINTER_COMPARISON_OPERATION_SET Macro
493 
494  // Expand into the various comparison operators needed.
501 
502  // These are here for expressions like "ptr == 0", "ptr != 0"
503  template<typename _Tp>
504  inline bool
505  operator==(const _Pointer_adapter<_Tp>& __lhs, int __rhs)
506  { return __lhs.get() == reinterpret_cast<void*>(__rhs); }
507 
508  template<typename _Tp>
509  inline bool
510  operator==(int __lhs, const _Pointer_adapter<_Tp>& __rhs)
511  { return __rhs.get() == reinterpret_cast<void*>(__lhs); }
512 
513  template<typename _Tp>
514  inline bool
515  operator!=(const _Pointer_adapter<_Tp>& __lhs, int __rhs)
516  { return __lhs.get() != reinterpret_cast<void*>(__rhs); }
517 
518  template<typename _Tp>
519  inline bool
520  operator!=(int __lhs, const _Pointer_adapter<_Tp>& __rhs)
521  { return __rhs.get() != reinterpret_cast<void*>(__lhs); }
522 
527  template<typename _Tp>
528  inline bool
529  operator==(const _Pointer_adapter<_Tp>& __lhs,
530  const _Pointer_adapter<_Tp>& __rhs)
531  { return __lhs._Tp::operator==(__rhs); }
532 
533  template<typename _Tp>
534  inline bool
535  operator<=(const _Pointer_adapter<_Tp>& __lhs,
536  const _Pointer_adapter<_Tp>& __rhs)
537  { return __lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs); }
538 
539  template<typename _Tp>
540  inline bool
541  operator!=(const _Pointer_adapter<_Tp>& __lhs,
542  const _Pointer_adapter<_Tp>& __rhs)
543  { return !(__lhs._Tp::operator==(__rhs)); }
544 
545  template<typename _Tp>
546  inline bool
547  operator>(const _Pointer_adapter<_Tp>& __lhs,
548  const _Pointer_adapter<_Tp>& __rhs)
549  { return !(__lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs)); }
550 
551  template<typename _Tp>
552  inline bool
553  operator>=(const _Pointer_adapter<_Tp>& __lhs,
554  const _Pointer_adapter<_Tp>& __rhs)
555  { return !(__lhs._Tp::operator<(__rhs)); }
556 
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()); }
562 
563 _GLIBCXX_END_NAMESPACE_VERSION
564 } // namespace
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)