16
16
#include < __type_traits/conditional.h>
17
17
#include < __type_traits/conjunction.h>
18
18
#include < __type_traits/decay.h>
19
+ #include < __type_traits/detected_or.h>
19
20
#include < __type_traits/enable_if.h>
21
+ #include < __type_traits/nat.h>
20
22
#include < __type_traits/integral_constant.h>
21
23
#include < __type_traits/is_class.h>
22
24
#include < __type_traits/is_function.h>
@@ -34,87 +36,46 @@ _LIBCPP_PUSH_MACROS
34
36
35
37
_LIBCPP_BEGIN_NAMESPACE_STD
36
38
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
-
51
39
template <class _Ptr >
52
- struct __pointer_traits_element_type <_Ptr, true > {
53
- using type _LIBCPP_NODEBUG = typename _Ptr::element_type;
54
- };
55
-
56
- template <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
- };
40
+ struct __pointer_traits_element_type_impl {};
60
41
61
42
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...> > {
63
44
using type _LIBCPP_NODEBUG = _Tp;
64
45
};
65
46
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> {};
76
49
77
50
template <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 ;
80
53
};
81
54
82
55
template <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
+ };
91
59
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...>;
94
63
};
95
64
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> > > {
98
70
#ifndef _LIBCPP_CXX03_LANG
99
71
using type _LIBCPP_NODEBUG = typename _Tp::template rebind<_Up>;
100
72
#else
101
73
using type _LIBCPP_NODEBUG = typename _Tp::template rebind<_Up>::other;
102
74
#endif
103
75
};
104
76
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 = typename _Tp::difference_type;
118
79
119
80
template <class _Ptr , class = void >
120
81
struct __pointer_traits_impl {};
@@ -123,7 +84,7 @@ template <class _Ptr>
123
84
struct __pointer_traits_impl <_Ptr, __void_t <typename __pointer_traits_element_type<_Ptr>::type> > {
124
85
typedef _Ptr pointer;
125
86
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>;
127
88
128
89
#ifndef _LIBCPP_CXX03_LANG
129
90
template <class _Up >
@@ -135,9 +96,6 @@ struct __pointer_traits_impl<_Ptr, __void_t<typename __pointer_traits_element_ty
135
96
};
136
97
#endif // _LIBCPP_CXX03_LANG
137
98
138
- private:
139
- struct __nat {};
140
-
141
99
public:
142
100
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer
143
101
pointer_to (__conditional_t <is_void<element_type>::value, __nat, element_type>& __r) {
@@ -164,9 +122,6 @@ struct pointer_traits<_Tp*> {
164
122
};
165
123
#endif
166
124
167
- private:
168
- struct __nat {};
169
-
170
125
public:
171
126
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer
172
127
pointer_to (__conditional_t <is_void<element_type>::value, __nat, element_type>& __r) _NOEXCEPT {
@@ -257,20 +212,23 @@ template <class _Tp>
257
212
struct __pointer_of {};
258
213
259
214
template <class _Tp >
260
- requires (__has_pointer<_Tp>::value)
215
+ concept __use_pointer_member = requires { typename _Tp::pointer; };
216
+
217
+ template <__use_pointer_member _Tp>
261
218
struct __pointer_of <_Tp> {
262
219
using type _LIBCPP_NODEBUG = typename _Tp::pointer;
263
220
};
264
221
265
222
template <class _Tp >
266
- requires (!__has_pointer<_Tp>::value && __has_element_type<_Tp>::value)
223
+ concept __use_element_type_member = !__use_pointer_member<_Tp> && requires { typename _Tp::element_type; };
224
+
225
+ template <__use_element_type_member _Tp>
267
226
struct __pointer_of <_Tp> {
268
227
using type _LIBCPP_NODEBUG = typename _Tp::element_type*;
269
228
};
270
229
271
230
template <class _Tp >
272
- requires (!__has_pointer<_Tp>::value && !__has_element_type<_Tp>::value &&
273
- __has_element_type<pointer_traits<_Tp>>::value)
231
+ requires (!__use_element_type_member<_Tp>)
274
232
struct __pointer_of<_Tp> {
275
233
using type _LIBCPP_NODEBUG = typename pointer_traits<_Tp>::element_type*;
276
234
};
0 commit comments