File indexing completed on 2026-05-03 08:13:35
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___MEMORY_POINTER_TRAITS_H
0011 #define _LIBCPP___CXX03___MEMORY_POINTER_TRAITS_H
0012
0013 #include <__cxx03/__config>
0014 #include <__cxx03/__memory/addressof.h>
0015 #include <__cxx03/__type_traits/conditional.h>
0016 #include <__cxx03/__type_traits/conjunction.h>
0017 #include <__cxx03/__type_traits/decay.h>
0018 #include <__cxx03/__type_traits/is_class.h>
0019 #include <__cxx03/__type_traits/is_function.h>
0020 #include <__cxx03/__type_traits/is_void.h>
0021 #include <__cxx03/__type_traits/void_t.h>
0022 #include <__cxx03/__utility/declval.h>
0023 #include <__cxx03/__utility/forward.h>
0024 #include <__cxx03/cstddef>
0025
0026 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0027 # pragma GCC system_header
0028 #endif
0029
0030 _LIBCPP_PUSH_MACROS
0031 #include <__cxx03/__undef_macros>
0032
0033 _LIBCPP_BEGIN_NAMESPACE_STD
0034
0035
0036 #define _LIBCPP_CLASS_TRAITS_HAS_XXX(NAME, PROPERTY) \
0037 template <class _Tp, class = void> \
0038 struct NAME : false_type {}; \
0039 template <class _Tp> \
0040 struct NAME<_Tp, __void_t<typename _Tp::PROPERTY> > : true_type {}
0041
0042
0043 _LIBCPP_CLASS_TRAITS_HAS_XXX(__has_pointer, pointer);
0044 _LIBCPP_CLASS_TRAITS_HAS_XXX(__has_element_type, element_type);
0045
0046 template <class _Ptr, bool = __has_element_type<_Ptr>::value>
0047 struct __pointer_traits_element_type {};
0048
0049 template <class _Ptr>
0050 struct __pointer_traits_element_type<_Ptr, true> {
0051 typedef _LIBCPP_NODEBUG typename _Ptr::element_type type;
0052 };
0053
0054 template <template <class, class...> class _Sp, class _Tp, class... _Args>
0055 struct __pointer_traits_element_type<_Sp<_Tp, _Args...>, true> {
0056 typedef _LIBCPP_NODEBUG typename _Sp<_Tp, _Args...>::element_type type;
0057 };
0058
0059 template <template <class, class...> class _Sp, class _Tp, class... _Args>
0060 struct __pointer_traits_element_type<_Sp<_Tp, _Args...>, false> {
0061 typedef _LIBCPP_NODEBUG _Tp type;
0062 };
0063
0064 template <class _Tp, class = void>
0065 struct __has_difference_type : false_type {};
0066
0067 template <class _Tp>
0068 struct __has_difference_type<_Tp, __void_t<typename _Tp::difference_type> > : true_type {};
0069
0070 template <class _Ptr, bool = __has_difference_type<_Ptr>::value>
0071 struct __pointer_traits_difference_type {
0072 typedef _LIBCPP_NODEBUG ptrdiff_t type;
0073 };
0074
0075 template <class _Ptr>
0076 struct __pointer_traits_difference_type<_Ptr, true> {
0077 typedef _LIBCPP_NODEBUG typename _Ptr::difference_type type;
0078 };
0079
0080 template <class _Tp, class _Up>
0081 struct __has_rebind {
0082 private:
0083 template <class _Xp>
0084 static false_type __test(...);
0085 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
0086 template <class _Xp>
0087 static true_type __test(typename _Xp::template rebind<_Up>* = 0);
0088 _LIBCPP_SUPPRESS_DEPRECATED_POP
0089
0090 public:
0091 static const bool value = decltype(__test<_Tp>(0))::value;
0092 };
0093
0094 template <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
0095 struct __pointer_traits_rebind {
0096 #ifndef _LIBCPP_CXX03_LANG
0097 typedef _LIBCPP_NODEBUG typename _Tp::template rebind<_Up> type;
0098 #else
0099 typedef _LIBCPP_NODEBUG typename _Tp::template rebind<_Up>::other type;
0100 #endif
0101 };
0102
0103 template <template <class, class...> class _Sp, class _Tp, class... _Args, class _Up>
0104 struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, true> {
0105 #ifndef _LIBCPP_CXX03_LANG
0106 typedef _LIBCPP_NODEBUG typename _Sp<_Tp, _Args...>::template rebind<_Up> type;
0107 #else
0108 typedef _LIBCPP_NODEBUG typename _Sp<_Tp, _Args...>::template rebind<_Up>::other type;
0109 #endif
0110 };
0111
0112 template <template <class, class...> class _Sp, class _Tp, class... _Args, class _Up>
0113 struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, false> {
0114 typedef _Sp<_Up, _Args...> type;
0115 };
0116
0117 template <class _Ptr, class = void>
0118 struct __pointer_traits_impl {};
0119
0120 template <class _Ptr>
0121 struct __pointer_traits_impl<_Ptr, __void_t<typename __pointer_traits_element_type<_Ptr>::type> > {
0122 typedef _Ptr pointer;
0123 typedef typename __pointer_traits_element_type<pointer>::type element_type;
0124 typedef typename __pointer_traits_difference_type<pointer>::type difference_type;
0125
0126 #ifndef _LIBCPP_CXX03_LANG
0127 template <class _Up>
0128 using rebind = typename __pointer_traits_rebind<pointer, _Up>::type;
0129 #else
0130 template <class _Up>
0131 struct rebind {
0132 typedef typename __pointer_traits_rebind<pointer, _Up>::type other;
0133 };
0134 #endif
0135
0136 private:
0137 struct __nat {};
0138
0139 public:
0140 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer
0141 pointer_to(__conditional_t<is_void<element_type>::value, __nat, element_type>& __r) {
0142 return pointer::pointer_to(__r);
0143 }
0144 };
0145
0146 template <class _Ptr>
0147 struct _LIBCPP_TEMPLATE_VIS pointer_traits : __pointer_traits_impl<_Ptr> {};
0148
0149 template <class _Tp>
0150 struct _LIBCPP_TEMPLATE_VIS pointer_traits<_Tp*> {
0151 typedef _Tp* pointer;
0152 typedef _Tp element_type;
0153 typedef ptrdiff_t difference_type;
0154
0155 #ifndef _LIBCPP_CXX03_LANG
0156 template <class _Up>
0157 using rebind = _Up*;
0158 #else
0159 template <class _Up>
0160 struct rebind {
0161 typedef _Up* other;
0162 };
0163 #endif
0164
0165 private:
0166 struct __nat {};
0167
0168 public:
0169 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer
0170 pointer_to(__conditional_t<is_void<element_type>::value, __nat, element_type>& __r) _NOEXCEPT {
0171 return std::addressof(__r);
0172 }
0173 };
0174
0175 #ifndef _LIBCPP_CXX03_LANG
0176 template <class _From, class _To>
0177 using __rebind_pointer_t = typename pointer_traits<_From>::template rebind<_To>;
0178 #else
0179 template <class _From, class _To>
0180 using __rebind_pointer_t = typename pointer_traits<_From>::template rebind<_To>::other;
0181 #endif
0182
0183
0184
0185 template <class _Pointer, class = void>
0186 struct __to_address_helper;
0187
0188 template <class _Tp>
0189 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __to_address(_Tp* __p) _NOEXCEPT {
0190 static_assert(!is_function<_Tp>::value, "_Tp is a function type");
0191 return __p;
0192 }
0193
0194 template <class _Pointer, class = void>
0195 struct _HasToAddress : false_type {};
0196
0197 template <class _Pointer>
0198 struct _HasToAddress<_Pointer, decltype((void)pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>())) >
0199 : true_type {};
0200
0201 template <class _Pointer, class = void>
0202 struct _HasArrow : false_type {};
0203
0204 template <class _Pointer>
0205 struct _HasArrow<_Pointer, decltype((void)std::declval<const _Pointer&>().operator->()) > : true_type {};
0206
0207 template <class _Pointer>
0208 struct _IsFancyPointer {
0209 static const bool value = _HasArrow<_Pointer>::value || _HasToAddress<_Pointer>::value;
0210 };
0211
0212
0213 template <class _Pointer, __enable_if_t< _And<is_class<_Pointer>, _IsFancyPointer<_Pointer> >::value, int> = 0>
0214 _LIBCPP_HIDE_FROM_ABI
0215 _LIBCPP_CONSTEXPR __decay_t<decltype(__to_address_helper<_Pointer>::__call(std::declval<const _Pointer&>()))>
0216 __to_address(const _Pointer& __p) _NOEXCEPT {
0217 return __to_address_helper<_Pointer>::__call(__p);
0218 }
0219
0220 template <class _Pointer, class>
0221 struct __to_address_helper {
0222 _LIBCPP_HIDE_FROM_ABI
0223 _LIBCPP_CONSTEXPR static decltype(std::__to_address(std::declval<const _Pointer&>().operator->()))
0224 __call(const _Pointer& __p) _NOEXCEPT {
0225 return std::__to_address(__p.operator->());
0226 }
0227 };
0228
0229 template <class _Pointer>
0230 struct __to_address_helper<_Pointer,
0231 decltype((void)pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>()))> {
0232 _LIBCPP_HIDE_FROM_ABI
0233 _LIBCPP_CONSTEXPR static decltype(pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>()))
0234 __call(const _Pointer& __p) _NOEXCEPT {
0235 return pointer_traits<_Pointer>::to_address(__p);
0236 }
0237 };
0238
0239 #if _LIBCPP_STD_VER >= 20
0240 template <class _Tp>
0241 inline _LIBCPP_HIDE_FROM_ABI constexpr auto to_address(_Tp* __p) noexcept {
0242 return std::__to_address(__p);
0243 }
0244
0245 template <class _Pointer>
0246 inline _LIBCPP_HIDE_FROM_ABI constexpr auto
0247 to_address(const _Pointer& __p) noexcept -> decltype(std::__to_address(__p)) {
0248 return std::__to_address(__p);
0249 }
0250 #endif
0251
0252 #if _LIBCPP_STD_VER >= 23
0253
0254 template <class _Tp>
0255 struct __pointer_of {};
0256
0257 template <class _Tp>
0258 requires(__has_pointer<_Tp>::value)
0259 struct __pointer_of<_Tp> {
0260 using type = typename _Tp::pointer;
0261 };
0262
0263 template <class _Tp>
0264 requires(!__has_pointer<_Tp>::value && __has_element_type<_Tp>::value)
0265 struct __pointer_of<_Tp> {
0266 using type = typename _Tp::element_type*;
0267 };
0268
0269 template <class _Tp>
0270 requires(!__has_pointer<_Tp>::value && !__has_element_type<_Tp>::value &&
0271 __has_element_type<pointer_traits<_Tp>>::value)
0272 struct __pointer_of<_Tp> {
0273 using type = typename pointer_traits<_Tp>::element_type*;
0274 };
0275
0276 template <typename _Tp>
0277 using __pointer_of_t = typename __pointer_of<_Tp>::type;
0278
0279 template <class _Tp, class _Up>
0280 struct __pointer_of_or {
0281 using type _LIBCPP_NODEBUG = _Up;
0282 };
0283
0284 template <class _Tp, class _Up>
0285 requires requires { typename __pointer_of_t<_Tp>; }
0286 struct __pointer_of_or<_Tp, _Up> {
0287 using type _LIBCPP_NODEBUG = __pointer_of_t<_Tp>;
0288 };
0289
0290 template <typename _Tp, typename _Up>
0291 using __pointer_of_or_t = typename __pointer_of_or<_Tp, _Up>::type;
0292
0293 template <class _Smart>
0294 concept __resettable_smart_pointer = requires(_Smart __s) { __s.reset(); };
0295
0296 template <class _Smart, class _Pointer, class... _Args>
0297 concept __resettable_smart_pointer_with_args = requires(_Smart __s, _Pointer __p, _Args... __args) {
0298 __s.reset(static_cast<__pointer_of_or_t<_Smart, _Pointer>>(__p), std::forward<_Args>(__args)...);
0299 };
0300
0301 #endif
0302
0303 _LIBCPP_END_NAMESPACE_STD
0304
0305 _LIBCPP_POP_MACROS
0306
0307 #endif