libstdc++
ptr_traits.h
Go to the documentation of this file.
1// Pointer Traits -*- C++ -*-
2
3// Copyright (C) 2011-2020 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
38namespace __gnu_debug { struct _Safe_iterator_base; }
39#endif
40
41namespace 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.
104 = __detected_or_t<__get_first_arg_t<_Ptr>, __element_type, _Ptr>;
105
106 /// The type used to represent the difference between two pointers.
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 _GLIBCXX20_CONSTEXPR 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>
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))
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
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:140
ISO C++ entities toplevel namespace is std.
typename pointer_traits< _Ptr >::template rebind< _Tp > __ptr_rebind
Convenience alias for rebinding pointers.
Definition: ptr_traits.h:151
GNU debug classes for public use.
is_function
Definition: type_traits:491
is_same
Definition: type_traits:1388
Uniform interface to all pointer-like types.
Definition: ptr_traits.h:83
__detected_or_t< __get_first_arg_t< _Ptr >, __element_type, _Ptr > element_type
The type pointed to.
Definition: ptr_traits.h:104
typename __rebind< _Ptr, _Up >::type rebind
A pointer to a different type.
Definition: ptr_traits.h:112
_Ptr pointer
The pointer type.
Definition: ptr_traits.h:100
__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
_Tp * pointer
The pointer type.
Definition: ptr_traits.h:130
ptrdiff_t difference_type
Type used to represent the difference between two pointers.
Definition: ptr_traits.h:134
_Tp element_type
The type pointed to.
Definition: ptr_traits.h:132
static constexpr pointer pointer_to(__make_not_void< element_type > &__r) noexcept
Obtain a pointer to an object.
Definition: ptr_traits.h:145