1515#include < __fwd/memory.h>
1616#include < __memory/construct_at.h>
1717#include < __memory/pointer_traits.h>
18+ #include < __type_traits/detected_or.h>
1819#include < __type_traits/enable_if.h>
1920#include < __type_traits/is_constructible.h>
2021#include < __type_traits/is_empty.h>
@@ -42,17 +43,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
4243 struct NAME <_Tp, __void_t <typename _Tp::PROPERTY > > : true_type {}
4344
4445// __pointer
45- template <class _Tp ,
46- class _Alloc ,
47- class _RawAlloc = __libcpp_remove_reference_t <_Alloc>,
48- bool = __has_pointer<_RawAlloc>::value>
49- struct __pointer {
50- using type _LIBCPP_NODEBUG = typename _RawAlloc::pointer;
51- };
52- template <class _Tp , class _Alloc , class _RawAlloc >
53- struct __pointer <_Tp, _Alloc, _RawAlloc, false > {
54- using type _LIBCPP_NODEBUG = _Tp*;
55- };
46+ template <class _Tp >
47+ using __pointer_member = typename _Tp::pointer;
48+
49+ template <class _Tp , class _Alloc >
50+ using __pointer = __detected_or_t <_Tp*, __pointer_member, __libcpp_remove_reference_t <_Alloc> >;
5651
5752// __const_pointer
5853_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX (__has_const_pointer, const_pointer);
@@ -100,13 +95,11 @@ struct __const_void_pointer<_Ptr, _Alloc, false> {
10095};
10196
10297// __size_type
103- _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX (__has_size_type, size_type);
104- template < class _Alloc , class _DiffType , bool = __has_size_type<_Alloc>::value>
105- struct __size_type : make_unsigned<_DiffType> {};
98+ template < class _Tp >
99+ using __size_type_member = typename _Tp::size_type;
100+
106101template <class _Alloc , class _DiffType >
107- struct __size_type <_Alloc, _DiffType, true > {
108- using type _LIBCPP_NODEBUG = typename _Alloc::size_type;
109- };
102+ using __size_type = __detected_or_t <__make_unsigned_t <_DiffType>, __size_type_member, _Alloc>;
110103
111104// __alloc_traits_difference_type
112105_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX (__has_alloc_traits_difference_type, difference_type);
@@ -120,40 +113,34 @@ struct __alloc_traits_difference_type<_Alloc, _Ptr, true> {
120113};
121114
122115// __propagate_on_container_copy_assignment
123- _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX (__has_propagate_on_container_copy_assignment, propagate_on_container_copy_assignment);
124- template < class _Alloc , bool = __has_propagate_on_container_copy_assignment<_Alloc>::value>
125- struct __propagate_on_container_copy_assignment : false_type {};
116+ template < class _Tp >
117+ using __propagate_on_container_copy_assignment_member = typename _Tp::propagate_on_container_copy_assignment;
118+
126119template <class _Alloc >
127- struct __propagate_on_container_copy_assignment <_Alloc, true > {
128- using type _LIBCPP_NODEBUG = typename _Alloc::propagate_on_container_copy_assignment;
129- };
120+ using __propagate_on_container_copy_assignment =
121+ __detected_or_t <false_type, __propagate_on_container_copy_assignment_member, _Alloc>;
130122
131123// __propagate_on_container_move_assignment
132- _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX (__has_propagate_on_container_move_assignment, propagate_on_container_move_assignment);
133- template < class _Alloc , bool = __has_propagate_on_container_move_assignment<_Alloc>::value>
134- struct __propagate_on_container_move_assignment : false_type {};
124+ template < class _Tp >
125+ using __propagate_on_container_move_assignment_member = typename _Tp::propagate_on_container_move_assignment;
126+
135127template <class _Alloc >
136- struct __propagate_on_container_move_assignment <_Alloc, true > {
137- using type _LIBCPP_NODEBUG = typename _Alloc::propagate_on_container_move_assignment;
138- };
128+ using __propagate_on_container_move_assignment =
129+ __detected_or_t <false_type, __propagate_on_container_move_assignment_member, _Alloc>;
139130
140131// __propagate_on_container_swap
141- _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX (__has_propagate_on_container_swap, propagate_on_container_swap);
142- template < class _Alloc , bool = __has_propagate_on_container_swap<_Alloc>::value>
143- struct __propagate_on_container_swap : false_type {};
132+ template < class _Tp >
133+ using __propagate_on_container_swap_member = typename _Tp::propagate_on_container_swap;
134+
144135template <class _Alloc >
145- struct __propagate_on_container_swap <_Alloc, true > {
146- using type _LIBCPP_NODEBUG = typename _Alloc::propagate_on_container_swap;
147- };
136+ using __propagate_on_container_swap = __detected_or_t <false_type, __propagate_on_container_swap_member, _Alloc>;
148137
149138// __is_always_equal
150- _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX (__has_is_always_equal, is_always_equal);
151- template < class _Alloc , bool = __has_is_always_equal<_Alloc>::value>
152- struct __is_always_equal : is_empty<_Alloc> {};
139+ template < class _Tp >
140+ using __is_always_equal_member = typename _Tp::is_always_equal;
141+
153142template <class _Alloc >
154- struct __is_always_equal <_Alloc, true > {
155- using type _LIBCPP_NODEBUG = typename _Alloc::is_always_equal;
156- };
143+ using __is_always_equal = __detected_or_t <typename is_empty<_Alloc>::type, __is_always_equal_member, _Alloc>;
157144
158145// __allocator_traits_rebind
159146_LIBCPP_SUPPRESS_DEPRECATED_PUSH
@@ -245,20 +232,18 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(allocation_result);
245232
246233template <class _Alloc >
247234struct _LIBCPP_TEMPLATE_VIS allocator_traits {
248- using allocator_type = _Alloc;
249- using value_type = typename allocator_type::value_type;
250- using pointer = typename __pointer<value_type, allocator_type>::type;
251- using const_pointer = typename __const_pointer<value_type, pointer, allocator_type>::type;
252- using void_pointer = typename __void_pointer<pointer, allocator_type>::type;
253- using const_void_pointer = typename __const_void_pointer<pointer, allocator_type>::type;
254- using difference_type = typename __alloc_traits_difference_type<allocator_type, pointer>::type;
255- using size_type = typename __size_type<allocator_type, difference_type>::type;
256- using propagate_on_container_copy_assignment =
257- typename __propagate_on_container_copy_assignment<allocator_type>::type;
258- using propagate_on_container_move_assignment =
259- typename __propagate_on_container_move_assignment<allocator_type>::type;
260- using propagate_on_container_swap = typename __propagate_on_container_swap<allocator_type>::type;
261- using is_always_equal = typename __is_always_equal<allocator_type>::type;
235+ using allocator_type = _Alloc;
236+ using value_type = typename allocator_type::value_type;
237+ using pointer = __pointer<value_type, allocator_type>;
238+ using const_pointer = typename __const_pointer<value_type, pointer, allocator_type>::type;
239+ using void_pointer = typename __void_pointer<pointer, allocator_type>::type;
240+ using const_void_pointer = typename __const_void_pointer<pointer, allocator_type>::type;
241+ using difference_type = typename __alloc_traits_difference_type<allocator_type, pointer>::type;
242+ using size_type = __size_type<allocator_type, difference_type>;
243+ using propagate_on_container_copy_assignment = __propagate_on_container_copy_assignment<allocator_type>;
244+ using propagate_on_container_move_assignment = __propagate_on_container_move_assignment<allocator_type>;
245+ using propagate_on_container_swap = __propagate_on_container_swap<allocator_type>;
246+ using is_always_equal = __is_always_equal<allocator_type>;
262247
263248#ifndef _LIBCPP_CXX03_LANG
264249 template <class _Tp >
0 commit comments