1616#include < __type_traits/conditional.h>
1717#include < __type_traits/conjunction.h>
1818#include < __type_traits/decay.h>
19+ #include < __type_traits/detected_or.h>
1920#include < __type_traits/enable_if.h>
2021#include < __type_traits/integral_constant.h>
2122#include < __type_traits/is_class.h>
2223#include < __type_traits/is_function.h>
2324#include < __type_traits/is_void.h>
25+ #include < __type_traits/nat.h>
2426#include < __type_traits/void_t.h>
2527#include < __utility/declval.h>
2628#include < __utility/forward.h>
@@ -34,87 +36,46 @@ _LIBCPP_PUSH_MACROS
3436
3537_LIBCPP_BEGIN_NAMESPACE_STD
3638
37- // clang-format off
38- #define _LIBCPP_CLASS_TRAITS_HAS_XXX (NAME, PROPERTY ) \
39- template <class _Tp , class = void > \
40- struct NAME : false_type {}; \
41- template <class _Tp > \
42- struct NAME <_Tp, __void_t <typename _Tp::PROPERTY> > : true_type {}
43- // clang-format on
44-
45- _LIBCPP_CLASS_TRAITS_HAS_XXX (__has_pointer, pointer);
46- _LIBCPP_CLASS_TRAITS_HAS_XXX (__has_element_type, element_type);
47-
48- template <class _Ptr , bool = __has_element_type<_Ptr>::value>
49- struct __pointer_traits_element_type {};
50-
5139template <class _Ptr >
52- struct __pointer_traits_element_type <_Ptr, true > {
53- using type _LIBCPP_NODEBUG = typename _Ptr::element_type;
54- };
40+ struct __pointer_traits_element_type_impl {};
5541
5642template <template <class , class ...> class _Sp , class _Tp , class ... _Args>
57- struct __pointer_traits_element_type <_Sp<_Tp, _Args...>, true > {
58- using type _LIBCPP_NODEBUG = typename _Sp<_Tp, _Args...>::element_type;
59- };
60-
61- template <template <class , class ...> class _Sp , class _Tp , class ... _Args>
62- struct __pointer_traits_element_type <_Sp<_Tp, _Args...>, false > {
43+ struct __pointer_traits_element_type_impl <_Sp<_Tp, _Args...> > {
6344 using type _LIBCPP_NODEBUG = _Tp;
6445};
6546
66- template <class _Tp , class = void >
67- struct __has_difference_type : false_type {};
68-
69- template <class _Tp >
70- struct __has_difference_type <_Tp, __void_t <typename _Tp::difference_type> > : true_type {};
71-
72- template <class _Ptr , bool = __has_difference_type<_Ptr>::value>
73- struct __pointer_traits_difference_type {
74- using type _LIBCPP_NODEBUG = ptrdiff_t ;
75- };
47+ template <class _Ptr , class = void >
48+ struct __pointer_traits_element_type : __pointer_traits_element_type_impl<_Ptr> {};
7649
7750template <class _Ptr >
78- struct __pointer_traits_difference_type <_Ptr, true > {
79- using type _LIBCPP_NODEBUG = typename _Ptr::difference_type ;
51+ struct __pointer_traits_element_type <_Ptr, __void_t < typename _Ptr::element_type> > {
52+ using type _LIBCPP_NODEBUG = typename _Ptr::element_type ;
8053};
8154
8255template <class _Tp , class _Up >
83- struct __has_rebind {
84- private:
85- template <class _Xp >
86- static false_type __test (...);
87- _LIBCPP_SUPPRESS_DEPRECATED_PUSH
88- template <class _Xp >
89- static true_type __test (typename _Xp::template rebind<_Up>* = 0 );
90- _LIBCPP_SUPPRESS_DEPRECATED_POP
56+ struct __pointer_traits_rebind_impl {
57+ static_assert (false , " Cannot rebind pointer; did you forget to add a rebind member to your pointer?" );
58+ };
9159
92- public:
93- static const bool value = decltype (__test<_Tp>(0 ))::value;
60+ template <template <class , class ...> class _Sp , class _Tp , class ... _Args, class _Up >
61+ struct __pointer_traits_rebind_impl <_Sp<_Tp, _Args...>, _Up> {
62+ using type _LIBCPP_NODEBUG = _Sp<_Up, _Args...>;
9463};
9564
96- template <class _Tp , class _Up , bool = __has_rebind<_Tp, _Up>::value>
97- struct __pointer_traits_rebind {
65+ template <class _Tp , class _Up , class = void >
66+ struct __pointer_traits_rebind : __pointer_traits_rebind_impl<_Tp, _Up> {};
67+
68+ template <class _Tp , class _Up >
69+ struct __pointer_traits_rebind <_Tp, _Up, __void_t <typename _Tp::template rebind<_Up> > > {
9870#ifndef _LIBCPP_CXX03_LANG
9971 using type _LIBCPP_NODEBUG = typename _Tp::template rebind<_Up>;
10072#else
10173 using type _LIBCPP_NODEBUG = typename _Tp::template rebind<_Up>::other;
10274#endif
10375};
10476
105- template <template <class , class ...> class _Sp , class _Tp , class ... _Args, class _Up >
106- struct __pointer_traits_rebind <_Sp<_Tp, _Args...>, _Up, true > {
107- #ifndef _LIBCPP_CXX03_LANG
108- using type _LIBCPP_NODEBUG = typename _Sp<_Tp, _Args...>::template rebind<_Up>;
109- #else
110- using type _LIBCPP_NODEBUG = typename _Sp<_Tp, _Args...>::template rebind<_Up>::other;
111- #endif
112- };
113-
114- template <template <class , class ...> class _Sp , class _Tp , class ... _Args, class _Up >
115- struct __pointer_traits_rebind <_Sp<_Tp, _Args...>, _Up, false > {
116- typedef _Sp<_Up, _Args...> type;
117- };
77+ template <class _Tp >
78+ using __difference_type_member _LIBCPP_NODEBUG = typename _Tp::difference_type;
11879
11980template <class _Ptr , class = void >
12081struct __pointer_traits_impl {};
@@ -123,7 +84,7 @@ template <class _Ptr>
12384struct __pointer_traits_impl <_Ptr, __void_t <typename __pointer_traits_element_type<_Ptr>::type> > {
12485 typedef _Ptr pointer;
12586 typedef typename __pointer_traits_element_type<pointer>::type element_type;
126- typedef typename __pointer_traits_difference_type< pointer>::type difference_type ;
87+ using difference_type = __detected_or_t < ptrdiff_t , __difference_type_member, pointer>;
12788
12889#ifndef _LIBCPP_CXX03_LANG
12990 template <class _Up >
@@ -135,9 +96,6 @@ struct __pointer_traits_impl<_Ptr, __void_t<typename __pointer_traits_element_ty
13596 };
13697#endif // _LIBCPP_CXX03_LANG
13798
138- private:
139- struct __nat {};
140-
14199public:
142100 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer
143101 pointer_to (__conditional_t <is_void<element_type>::value, __nat, element_type>& __r) {
@@ -164,9 +122,6 @@ struct pointer_traits<_Tp*> {
164122 };
165123#endif
166124
167- private:
168- struct __nat {};
169-
170125public:
171126 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer
172127 pointer_to (__conditional_t <is_void<element_type>::value, __nat, element_type>& __r) _NOEXCEPT {
@@ -257,40 +212,35 @@ template <class _Tp>
257212struct __pointer_of {};
258213
259214template <class _Tp >
260- requires (__has_pointer<_Tp>::value)
215+ concept __has_pointer_member = requires { typename _Tp::pointer; };
216+
217+ template <class _Tp >
218+ concept __has_element_type_member = requires { typename _Tp::element_type; };
219+
220+ template <class _Tp >
221+ requires __has_pointer_member<_Tp>
261222struct __pointer_of <_Tp> {
262223 using type _LIBCPP_NODEBUG = typename _Tp::pointer;
263224};
264225
265226template <class _Tp >
266- requires (!__has_pointer <_Tp>::value && __has_element_type <_Tp>::value )
227+ requires (!__has_pointer_member <_Tp> && __has_element_type_member <_Tp>)
267228struct __pointer_of<_Tp> {
268229 using type _LIBCPP_NODEBUG = typename _Tp::element_type*;
269230};
270231
271232template <class _Tp >
272- requires (!__has_pointer <_Tp>::value && !__has_element_type <_Tp>::value &&
273- __has_element_type <pointer_traits<_Tp>>::value )
233+ requires (!__has_pointer_member <_Tp> && !__has_element_type_member <_Tp> &&
234+ __has_element_type_member <pointer_traits<_Tp>>)
274235struct __pointer_of<_Tp> {
275236 using type _LIBCPP_NODEBUG = typename pointer_traits<_Tp>::element_type*;
276237};
277238
278239template <typename _Tp>
279240using __pointer_of_t _LIBCPP_NODEBUG = typename __pointer_of<_Tp>::type;
280241
281- template <class _Tp , class _Up >
282- struct __pointer_of_or {
283- using type _LIBCPP_NODEBUG = _Up;
284- };
285-
286- template <class _Tp , class _Up >
287- requires requires { typename __pointer_of_t <_Tp>; }
288- struct __pointer_of_or <_Tp, _Up> {
289- using type _LIBCPP_NODEBUG = __pointer_of_t <_Tp>;
290- };
291-
292242template <typename _Tp, typename _Up>
293- using __pointer_of_or_t _LIBCPP_NODEBUG = typename __pointer_of_or<_Tp, _Up>::type ;
243+ using __pointer_of_or_t _LIBCPP_NODEBUG = __detected_or_t <_Up, __pointer_of_t , _Tp> ;
294244
295245template <class _Smart >
296246concept __resettable_smart_pointer = requires (_Smart __s) { __s.reset (); };
0 commit comments