• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/toolchains/hndtools-armeabi-2013.11/arm-none-eabi/include/c++/4.8.1/ext/
1// Custom pointer adapter and sample storage policies
2
3// Copyright (C) 2008-2013 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23// <http://www.gnu.org/licenses/>.
24
25/**
26 *  @file ext/pointer.h
27 *  This file is a GNU extension to the Standard C++ Library.
28 *
29 *  @author Bob Walters
30 *
31 * Provides reusable _Pointer_adapter for assisting in the development of
32 * custom pointer types that can be used with the standard containers via
33 * the allocator::pointer and allocator::const_pointer typedefs.
34 */
35
36#ifndef _POINTER_H
37#define _POINTER_H 1
38
39#pragma GCC system_header
40
41#include <iosfwd>
42#include <bits/stl_iterator_base_types.h>
43#include <ext/cast.h>
44#include <ext/type_traits.h>
45#if __cplusplus >= 201103L
46# include <bits/move.h>
47# include <bits/ptr_traits.h>
48#endif
49
50namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
51{
52_GLIBCXX_BEGIN_NAMESPACE_VERSION
53
54  /**
55   * @brief A storage policy for use with _Pointer_adapter<> which yields a
56   *        standard pointer.
57   *
58   *  A _Storage_policy is required to provide 4 things:
59   *    1) A get() API for returning the stored pointer value.
60   *    2) An set() API for storing a pointer value.
61   *    3) An element_type typedef to define the type this points to.
62   *    4) An operator<() to support pointer comparison.
63   *    5) An operator==() to support pointer comparison.
64   */
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
95  /**
96   * @brief A storage policy for use with _Pointer_adapter<> which stores
97   *        the pointer's address as an offset value which is relative to
98   *        its own address.
99   *
100   * This is intended for pointers within shared memory regions which
101   * might be mapped at different addresses by different processes.
102   * For null pointers, a value of 1 is used.  (0 is legitimate
103   * sometimes for nodes in circularly linked lists) This value was
104   * chosen as the least likely to generate an incorrect null, As
105   * there is no reason why any normal pointer would point 1 byte into
106   * its own pointer address.
107   */
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
156  /**
157   * Relative_pointer_impl needs a specialization for const T because of
158   * the casting done during pointer arithmetic.
159   */
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
208  /**
209   * The specialization on this type helps resolve the problem of
210   * reference to void, and eliminates the need to specialize
211   * _Pointer_adapter for cases of void*, const void*, and so on.
212   */
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
235  /**
236   * This structure accommodates the way in which
237   * std::iterator_traits<> is normally specialized for const T*, so
238   * that value_type is still T.
239   */
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
248  /**
249   * The following provides an 'alternative pointer' that works with
250   * the containers when specified as the pointer typedef of the
251   * allocator.
252   *
253   * The pointer type used with the containers doesn't have to be this
254   * class, but it must support the implicit conversions, pointer
255   * arithmetic, comparison operators, etc. that are supported by this
256   * class, and avoid raising compile-time ambiguities.  Because
257   * creating a working pointer can be challenging, this pointer
258   * template was designed to wrapper an easier storage policy type,
259   * so that it becomes reusable for creating other pointer types.
260   *
261   * A key point of this class is also that it allows container
262   * writers to 'assume' Allocator::pointer is a typedef for a normal
263   * pointer.  This class supports most of the conventions of a true
264   * pointer, and can, for instance handle implicit conversion to
265   * const and base class pointer types.  The only impositions on
266   * container writers to support extended pointers are: 1) use the
267   * Allocator::pointer typedef appropriately for pointer types.  2)
268   * if you need pointer casting, use the __pointer_cast<> functions
269   * from ext/cast.h.  This allows pointer cast operations to be
270   * overloaded as necessary by custom pointers.
271   *
272   * Note: The const qualifier works with this pointer adapter as
273   * follows:
274   *
275   * _Tp*             == _Pointer_adapter<_Std_pointer_impl<_Tp> >;
276   * const _Tp*       == _Pointer_adapter<_Std_pointer_impl<const _Tp> >;
277   * _Tp* const       == const _Pointer_adapter<_Std_pointer_impl<_Tp> >;
278   * const _Tp* const == const _Pointer_adapter<_Std_pointer_impl<const _Tp> >;
279   */
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.
434      _CXX_POINTER_ARITH_OPERATOR_SET(short);
435      _CXX_POINTER_ARITH_OPERATOR_SET(unsigned short);
436      _CXX_POINTER_ARITH_OPERATOR_SET(int);
437      _CXX_POINTER_ARITH_OPERATOR_SET(unsigned int);
438      _CXX_POINTER_ARITH_OPERATOR_SET(long);
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.
495  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(==)
496  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(!=)
497  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<)
498  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<=)
499  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>)
500  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>=)
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
523  /**
524   * Comparison operators for _Pointer_adapter defer to the base class'
525   * comparison operators, when possible.
526   */
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
565
566#if __cplusplus >= 201103L
567namespace std _GLIBCXX_VISIBILITY(default)
568{
569_GLIBCXX_BEGIN_NAMESPACE_VERSION
570
571  template<typename _Storage_policy>
572    struct pointer_traits<__gnu_cxx::_Pointer_adapter<_Storage_policy>>
573    {
574      /// The pointer type
575      typedef __gnu_cxx::_Pointer_adapter<_Storage_policy>         pointer;
576      /// The type pointed to
577      typedef typename pointer::element_type            element_type;
578      /// Type used to represent the difference between two pointers
579      typedef typename pointer::difference_type         difference_type;
580
581      template<typename _Up>
582        using rebind = typename __gnu_cxx::_Pointer_adapter<
583	typename pointer_traits<_Storage_policy>::rebind<_Up>>;
584
585      static pointer pointer_to(typename pointer::reference __r) noexcept
586      { return pointer(std::addressof(__r)); }
587    };
588
589_GLIBCXX_END_NAMESPACE_VERSION
590} // namespace
591#endif
592
593#endif // _POINTER_H
594