Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/bits/ptr_traits.h
1 // Pointer Traits -*- C++ -*- 2 3 // Copyright (C) 2011-2025 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 #include <concepts> 39 namespace __gnu_debug { struct _Safe_iterator_base; } 40 #endif 41 42 namespace std _GLIBCXX_VISIBILITY(default) 43 { 44 _GLIBCXX_BEGIN_NAMESPACE_VERSION 45 46 /// @cond undocumented 47 48 class __undefined; 49 50 // For a specialization `SomeTemplate<T, Types...>` the member `type` is T, 51 // otherwise `type` is `__undefined`. 52 template<typename _Tp> 53 struct __get_first_arg 54 { using type = __undefined; }; 55 56 template<template<typename, typename...> class _SomeTemplate, typename _Tp, 57 typename... _Types> 58 struct __get_first_arg<_SomeTemplate<_Tp, _Types...>> 59 { using type = _Tp; }; 60 61 // For a specialization `SomeTemplate<T, Args...>` and a type `U` the member 62 // `type` is `SomeTemplate<U, Args...>`, otherwise there is no member `type`. 63 template<typename _Tp, typename _Up> 64 struct __replace_first_arg 65 { }; 66 67 template<template<typename, typename...> class _SomeTemplate, typename _Up, 68 typename _Tp, typename... _Types> 69 struct __replace_first_arg<_SomeTemplate<_Tp, _Types...>, _Up> 70 { using type = _SomeTemplate<_Up, _Types...>; }; 71 72 // Detect the element type of a pointer-like type. 73 template<typename _Ptr, typename = void> 74 struct __ptr_traits_elem : __get_first_arg<_Ptr> 75 { }; 76 77 // Use _Ptr::element_type if is a valid type. 78 #if __cpp_concepts 79 template<typename _Ptr> requires requires { typename _Ptr::element_type; } 80 struct __ptr_traits_elem<_Ptr, void> 81 { using type = typename _Ptr::element_type; }; 82 #else 83 template<typename _Ptr> 84 struct __ptr_traits_elem<_Ptr, __void_t<typename _Ptr::element_type>> 85 { using type = typename _Ptr::element_type; }; 86 #endif 87 88 template<typename _Ptr> 89 using __ptr_traits_elem_t = typename __ptr_traits_elem<_Ptr>::type; 90 91 /// @endcond 92 93 // Define pointer_traits<P>::pointer_to. 94 template<typename _Ptr, typename _Elt, bool = is_void<_Elt>::value> 95 struct __ptr_traits_ptr_to 96 { 97 using pointer = _Ptr; 98 using element_type = _Elt; 99 100 /** 101 * @brief Obtain a pointer to an object 102 * @param __r A reference to an object of type `element_type` 103 * @return `pointer::pointer_to(__r)` 104 * @pre `pointer::pointer_to(__r)` is a valid expression. 105 */ 106 static pointer 107 pointer_to(element_type& __r) 108 #if __cpp_lib_concepts 109 requires requires { 110 { pointer::pointer_to(__r) } -> convertible_to<pointer>; 111 } 112 #endif 113 { return pointer::pointer_to(__r); } 114 }; 115 116 // Do not define pointer_traits<P>::pointer_to if element type is void. 117 template<typename _Ptr, typename _Elt> 118 struct __ptr_traits_ptr_to<_Ptr, _Elt, true> 119 { }; 120 121 // Partial specialization defining pointer_traits<T*>::pointer_to(T&). 122 template<typename _Tp> 123 struct __ptr_traits_ptr_to<_Tp*, _Tp, false> 124 { 125 using pointer = _Tp*; 126 using element_type = _Tp; 127 128 /** 129 * @brief Obtain a pointer to an object 130 * @param __r A reference to an object of type `element_type` 131 * @return `addressof(__r)` 132 */ 133 static _GLIBCXX20_CONSTEXPR pointer 134 pointer_to(element_type& __r) noexcept 135 { return std::addressof(__r); } 136 }; 137 138 template<typename _Ptr, typename _Elt> 139 struct __ptr_traits_impl : __ptr_traits_ptr_to<_Ptr, _Elt> 140 { 141 private: 142 template<typename _Tp> 143 using __diff_t = typename _Tp::difference_type; 144 145 template<typename _Tp, typename _Up> 146 using __rebind = __type_identity<typename _Tp::template rebind<_Up>>; 147 148 public: 149 /// The pointer type. 150 using pointer = _Ptr; 151 152 /// The type pointed to. 153 using element_type = _Elt; 154 155 /// The type used to represent the difference between two pointers. 156 using difference_type = __detected_or_t<ptrdiff_t, __diff_t, _Ptr>; 157 158 /// A pointer to a different type. 159 template<typename _Up> 160 using rebind = typename __detected_or_t<__replace_first_arg<_Ptr, _Up>, 161 __rebind, _Ptr, _Up>::type; 162 }; 163 164 // _GLIBCXX_RESOLVE_LIB_DEFECTS 165 // 3545. std::pointer_traits should be SFINAE-friendly 166 template<typename _Ptr> 167 struct __ptr_traits_impl<_Ptr, __undefined> 168 { }; 169 170 /** 171 * @brief Uniform interface to all pointer-like types 172 * @headerfile memory 173 * @ingroup pointer_abstractions 174 * @since C++11 175 */ 176 template<typename _Ptr> 177 struct pointer_traits : __ptr_traits_impl<_Ptr, __ptr_traits_elem_t<_Ptr>> 178 { }; 179 180 /** 181 * @brief Partial specialization for built-in pointers. 182 * @headerfile memory 183 * @ingroup pointer_abstractions 184 * @since C++11 185 */ 186 template<typename _Tp> 187 struct pointer_traits<_Tp*> : __ptr_traits_ptr_to<_Tp*, _Tp> 188 { 189 /// The pointer type 190 typedef _Tp* pointer; 191 /// The type pointed to 192 typedef _Tp element_type; 193 /// Type used to represent the difference between two pointers 194 typedef ptrdiff_t difference_type; 195 /// A pointer to a different type. 196 template<typename _Up> using rebind = _Up*; 197 }; 198 199 /// Convenience alias for rebinding pointers. 200 template<typename _Ptr, typename _Tp> 201 using __ptr_rebind = typename pointer_traits<_Ptr>::template rebind<_Tp>; 202 203 #ifndef __glibcxx_to_address // C++ < 20 204 template<typename _Tp> 205 [[__gnu__::__always_inline__]] 206 constexpr _Tp* 207 __to_address(_Tp* __ptr) noexcept 208 { 209 static_assert(!std::is_function<_Tp>::value, "std::to_address argument " 210 "must not be a function pointer"); 211 return __ptr; 212 } 213 214 // This should only be used for pointer-like types (e.g. allocator pointers) 215 // and (in C++20 and later) for types satisfying std::contiguous_iterator. 216 // It should not be used for arbitrary random access iterators, because 217 // they might not be contiguous iterators (e.g. deque::iterator isn't). 218 template<typename _Ptr> 219 constexpr typename std::pointer_traits<_Ptr>::element_type* 220 __to_address(const _Ptr& __ptr) 221 { return std::__to_address(__ptr.operator->()); } 222 #else 223 /** 224 * @brief Obtain address referenced by a pointer to an object 225 * @param __ptr A pointer to an object 226 * @return @c __ptr 227 * @ingroup pointer_abstractions 228 */ 229 template<typename _Tp> 230 [[__gnu__::__always_inline__]] 231 constexpr _Tp* 232 to_address(_Tp* __ptr) noexcept 233 { 234 static_assert(!is_function_v<_Tp>, "std::to_address argument " 235 "must not be a function pointer"); 236 return __ptr; 237 } 238 239 /** 240 * @brief Obtain address referenced by a pointer to an object 241 * @param __ptr A pointer to an object 242 * @return @c pointer_traits<_Ptr>::to_address(__ptr) if that expression is 243 well-formed, otherwise @c to_address(__ptr.operator->()) 244 * @ingroup pointer_abstractions 245 */ 246 template<typename _Ptr> 247 constexpr auto 248 to_address(const _Ptr& __ptr) noexcept 249 { 250 if constexpr (requires { pointer_traits<_Ptr>::to_address(__ptr); }) 251 return pointer_traits<_Ptr>::to_address(__ptr); 252 else if constexpr (is_base_of_v<__gnu_debug::_Safe_iterator_base, _Ptr>) 253 return std::to_address(__ptr.base().operator->()); 254 else 255 return std::to_address(__ptr.operator->()); 256 } 257 258 /// @cond undocumented 259 /// Compatibility for use in code that is also compiled as pre-C++20. 260 template<typename _Ptr> 261 [[__gnu__::__always_inline__]] 262 constexpr auto 263 __to_address(const _Ptr& __ptr) noexcept 264 { return std::to_address(__ptr); } 265 /// @endcond 266 #endif // __glibcxx_to_address 267 268 _GLIBCXX_END_NAMESPACE_VERSION 269 } // namespace std 270 271 #endif 272 273 #endif