libstdc++
ptr_traits.h
Go to the documentation of this file.
1 // Pointer Traits -*- C++ -*-
2 
3 // Copyright (C) 2011-2018 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 /** @file bits/ptr_traits.h
26  * This is an internal header file, included by other library headers.
27  * Do not attempt to use it directly. @headername{memory}
28  */
29 
30 #ifndef _PTR_TRAITS_H
31 #define _PTR_TRAITS_H 1
32 
33 #if __cplusplus >= 201103L
34 
35 #include <bits/move.h>
36 
37 #if __cplusplus > 201703L
38 namespace __gnu_debug { struct _Safe_iterator_base; }
39 #endif
40 
41 namespace std _GLIBCXX_VISIBILITY(default)
42 {
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
44 
45  class __undefined;
46 
47  // Given Template<T, ...> return T, otherwise invalid.
48  template<typename _Tp>
49  struct __get_first_arg
50  { using type = __undefined; };
51 
52  template<template<typename, typename...> class _Template, typename _Tp,
53  typename... _Types>
54  struct __get_first_arg<_Template<_Tp, _Types...>>
55  { using type = _Tp; };
56 
57  template<typename _Tp>
58  using __get_first_arg_t = typename __get_first_arg<_Tp>::type;
59 
60  // Given Template<T, ...> and U return Template<U, ...>, otherwise invalid.
61  template<typename _Tp, typename _Up>
62  struct __replace_first_arg
63  { };
64 
65  template<template<typename, typename...> class _Template, typename _Up,
66  typename _Tp, typename... _Types>
67  struct __replace_first_arg<_Template<_Tp, _Types...>, _Up>
68  { using type = _Template<_Up, _Types...>; };
69 
70  template<typename _Tp, typename _Up>
71  using __replace_first_arg_t = typename __replace_first_arg<_Tp, _Up>::type;
72 
73  template<typename _Tp>
74  using __make_not_void
75  = typename conditional<is_void<_Tp>::value, __undefined, _Tp>::type;
76 
77  /**
78  * @brief Uniform interface to all pointer-like types
79  * @ingroup pointer_abstractions
80  */
81  template<typename _Ptr>
83  {
84  private:
85  template<typename _Tp>
86  using __element_type = typename _Tp::element_type;
87 
88  template<typename _Tp>
89  using __difference_type = typename _Tp::difference_type;
90 
91  template<typename _Tp, typename _Up, typename = void>
92  struct __rebind : __replace_first_arg<_Tp, _Up> { };
93 
94  template<typename _Tp, typename _Up>
95  struct __rebind<_Tp, _Up, __void_t<typename _Tp::template rebind<_Up>>>
96  { using type = typename _Tp::template rebind<_Up>; };
97 
98  public:
99  /// The pointer type.
100  using pointer = _Ptr;
101 
102  /// The type pointed to.
103  using element_type
104  = __detected_or_t<__get_first_arg_t<_Ptr>, __element_type, _Ptr>;
105 
106  /// The type used to represent the difference between two pointers.
107  using difference_type
108  = __detected_or_t<ptrdiff_t, __difference_type, _Ptr>;
109 
110  /// A pointer to a different type.
111  template<typename _Up>
112  using rebind = typename __rebind<_Ptr, _Up>::type;
113 
114  static _Ptr
115  pointer_to(__make_not_void<element_type>& __e)
116  { return _Ptr::pointer_to(__e); }
117 
119  "pointer type defines element_type or is like SomePointer<T, Args>");
120  };
121 
122  /**
123  * @brief Partial specialization for built-in pointers.
124  * @ingroup pointer_abstractions
125  */
126  template<typename _Tp>
127  struct pointer_traits<_Tp*>
128  {
129  /// The pointer type
130  typedef _Tp* pointer;
131  /// The type pointed to
132  typedef _Tp element_type;
133  /// Type used to represent the difference between two pointers
134  typedef ptrdiff_t difference_type;
135 
136  template<typename _Up>
137  using rebind = _Up*;
138 
139  /**
140  * @brief Obtain a pointer to an object
141  * @param __r A reference to an object of type @c element_type
142  * @return @c addressof(__r)
143  */
144  static pointer
145  pointer_to(__make_not_void<element_type>& __r) noexcept
146  { return std::addressof(__r); }
147  };
148 
149  /// Convenience alias for rebinding pointers.
150  template<typename _Ptr, typename _Tp>
151  using __ptr_rebind = typename pointer_traits<_Ptr>::template rebind<_Tp>;
152 
153  template<typename _Tp>
154  constexpr _Tp*
155  __to_address(_Tp* __ptr) noexcept
156  {
157  static_assert(!std::is_function<_Tp>::value, "not a function pointer");
158  return __ptr;
159  }
160 
161 #if __cplusplus <= 201703L
162  template<typename _Ptr>
163  constexpr typename std::pointer_traits<_Ptr>::element_type*
164  __to_address(const _Ptr& __ptr)
165  { return std::__to_address(__ptr.operator->()); }
166 #else
167  template<typename _Ptr>
168  constexpr auto
169  __to_address(const _Ptr& __ptr) noexcept
170  -> decltype(std::pointer_traits<_Ptr>::to_address(__ptr))
171  { return std::pointer_traits<_Ptr>::to_address(__ptr); }
172 
173  template<typename _Ptr, typename... _None>
174  constexpr auto
175  __to_address(const _Ptr& __ptr, _None...) noexcept
176  {
177  if constexpr (is_base_of_v<__gnu_debug::_Safe_iterator_base, _Ptr>)
178  return std::__to_address(__ptr.base().operator->());
179  else
180  return std::__to_address(__ptr.operator->());
181  }
182 
183  /**
184  * @brief Obtain address referenced by a pointer to an object
185  * @param __ptr A pointer to an object
186  * @return @c __ptr
187  * @ingroup pointer_abstractions
188  */
189  template<typename _Tp>
190  constexpr _Tp*
191  to_address(_Tp* __ptr) noexcept
192  { return std::__to_address(__ptr); }
193 
194  /**
195  * @brief Obtain address referenced by a pointer to an object
196  * @param __ptr A pointer to an object
197  * @return @c pointer_traits<_Ptr>::to_address(__ptr) if that expression is
198  well-formed, otherwise @c to_address(__ptr.operator->())
199  * @ingroup pointer_abstractions
200  */
201  template<typename _Ptr>
202  constexpr auto
203  to_address(const _Ptr& __ptr) noexcept
204  { return std::__to_address(__ptr); }
205 #endif // C++2a
206 
207 _GLIBCXX_END_NAMESPACE_VERSION
208 } // namespace std
209 
210 #endif
211 
212 #endif
GNU debug classes for public use.
Uniform interface to all pointer-like types.
Definition: ptr_traits.h:82
ptrdiff_t difference_type
Type used to represent the difference between two pointers.
Definition: ptr_traits.h:134
is_function
Definition: type_traits:391
_Tp * pointer
The pointer type.
Definition: ptr_traits.h:130
__detected_or_t< ptrdiff_t, __difference_type, _Ptr > difference_type
The type used to represent the difference between two pointers.
Definition: ptr_traits.h:108
typename __rebind< _Ptr, _Up >::type rebind
A pointer to a different type.
Definition: ptr_traits.h:112
_GLIBCXX17_CONSTEXPR _Tp * addressof(_Tp &__r) noexcept
Returns the actual address of the object or function referenced by r, even in the presence of an over...
Definition: move.h:138
is_same
Definition: type_traits:1279
ISO C++ entities toplevel namespace is std.
static pointer pointer_to(__make_not_void< element_type > &__r) noexcept
Obtain a pointer to an object.
Definition: ptr_traits.h:145
_Ptr pointer
The pointer type.
Definition: ptr_traits.h:100
__detected_or_t< __get_first_arg_t< _Ptr >, __element_type, _Ptr > element_type
The type pointed to.
Definition: ptr_traits.h:104
typename pointer_traits< _Ptr >::template rebind< _Tp > __ptr_rebind
Convenience alias for rebinding pointers.
Definition: ptr_traits.h:151
_Tp element_type
The type pointed to.
Definition: ptr_traits.h:132