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