authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-01-17 05:40:55+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-04-25 21:49:39+02:00
logdfabf1586fa2fcd9350e204fa138f44f952acbfd
tree0772d518264f9deab3eb70b04167bb5df72ac88f
parent80212b03ff792ddfff82092b35aa7ed0fdf937a8
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

libcxx: update to LLVM 22


425 files changed, 15825 insertions(+), 10341 deletions(-)

lib/libcxx/include/__algorithm/all_of.h+11-5
......@@ -10,24 +10,28 @@
1010#ifndef _LIBCPP___ALGORITHM_ALL_OF_H
1111#define _LIBCPP___ALGORITHM_ALL_OF_H
1212
13#include <__algorithm/any_of.h>
1314#include <__config>
1415#include <__functional/identity.h>
1516#include <__type_traits/invoke.h>
17#include <__utility/forward.h>
18#include <__utility/move.h>
1619
1720#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1821# pragma GCC system_header
1922#endif
2023
24_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
2127_LIBCPP_BEGIN_NAMESPACE_STD
2228
2329template <class _Iter, class _Sent, class _Proj, class _Pred>
2430_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
2531__all_of(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
26 for (; __first != __last; ++__first) {
27 if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
28 return false;
29 }
30 return true;
32 using _Ref = decltype(std::__invoke(__proj, *__first));
33 auto __negated_pred = [&__pred](_Ref __arg) -> bool { return !std::__invoke(__pred, std::forward<_Ref>(__arg)); };
34 return !std::__any_of(std::move(__first), std::move(__last), __negated_pred, __proj);
3135}
3236
3337template <class _InputIterator, class _Predicate>
......@@ -39,4 +43,6 @@ all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
3943
4044_LIBCPP_END_NAMESPACE_STD
4145
46_LIBCPP_POP_MACROS
47
4248#endif // _LIBCPP___ALGORITHM_ALL_OF_H
lib/libcxx/include/__algorithm/comp.h+4
......@@ -11,6 +11,7 @@
1111
1212#include <__config>
1313#include <__type_traits/desugars_to.h>
14#include <__type_traits/is_generic_transparent_comparator.h>
1415#include <__type_traits/is_integral.h>
1516
1617#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -48,6 +49,9 @@ inline const bool __desugars_to_v<__less_tag, __less<>, _Tp, _Tp> = true;
4849template <class _Tp>
4950inline const bool __desugars_to_v<__totally_ordered_less_tag, __less<>, _Tp, _Tp> = is_integral<_Tp>::value;
5051
52template <>
53inline const bool __is_generic_transparent_comparator_v<__less<> > = true;
54
5155_LIBCPP_END_NAMESPACE_STD
5256
5357#endif // _LIBCPP___ALGORITHM_COMP_H
lib/libcxx/include/__algorithm/copy.h+28-147
......@@ -12,11 +12,10 @@
1212#include <__algorithm/copy_move_common.h>
1313#include <__algorithm/for_each_segment.h>
1414#include <__algorithm/min.h>
15#include <__algorithm/specialized_algorithms.h>
1516#include <__config>
16#include <__fwd/bit_reference.h>
1717#include <__iterator/iterator_traits.h>
1818#include <__iterator/segmented_iterator.h>
19#include <__memory/pointer_traits.h>
2019#include <__type_traits/common_type.h>
2120#include <__type_traits/enable_if.h>
2221#include <__utility/move.h>
......@@ -38,124 +37,14 @@ copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result);
3837template <class _InIter, class _Sent, class _OutIter>
3938inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __copy(_InIter, _Sent, _OutIter);
4039
41template <class _Cp, bool _IsConst>
42_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_aligned(
43 __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
44 using _In = __bit_iterator<_Cp, _IsConst>;
45 using difference_type = typename _In::difference_type;
46 using __storage_type = typename _In::__storage_type;
47
48 const int __bits_per_word = _In::__bits_per_word;
49 difference_type __n = __last - __first;
50 if (__n > 0) {
51 // do first word
52 if (__first.__ctz_ != 0) {
53 unsigned __clz = __bits_per_word - __first.__ctz_;
54 difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
55 __n -= __dn;
56 __storage_type __m = std::__middle_mask<__storage_type>(__clz - __dn, __first.__ctz_);
57 __storage_type __b = *__first.__seg_ & __m;
58 *__result.__seg_ &= ~__m;
59 *__result.__seg_ |= __b;
60 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
61 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
62 ++__first.__seg_;
63 // __first.__ctz_ = 0;
64 }
65 // __first.__ctz_ == 0;
66 // do middle words
67 __storage_type __nw = __n / __bits_per_word;
68 std::copy(std::__to_address(__first.__seg_),
69 std::__to_address(__first.__seg_ + __nw),
70 std::__to_address(__result.__seg_));
71 __n -= __nw * __bits_per_word;
72 __result.__seg_ += __nw;
73 // do last word
74 if (__n > 0) {
75 __first.__seg_ += __nw;
76 __storage_type __m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
77 __storage_type __b = *__first.__seg_ & __m;
78 *__result.__seg_ &= ~__m;
79 *__result.__seg_ |= __b;
80 __result.__ctz_ = static_cast<unsigned>(__n);
81 }
82 }
83 return __result;
84}
85
86template <class _Cp, bool _IsConst>
87_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_unaligned(
88 __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
89 using _In = __bit_iterator<_Cp, _IsConst>;
90 using difference_type = typename _In::difference_type;
91 using __storage_type = typename _In::__storage_type;
92
93 const int __bits_per_word = _In::__bits_per_word;
94 difference_type __n = __last - __first;
95 if (__n > 0) {
96 // do first word
97 if (__first.__ctz_ != 0) {
98 unsigned __clz_f = __bits_per_word - __first.__ctz_;
99 difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
100 __n -= __dn;
101 __storage_type __m = std::__middle_mask<__storage_type>(__clz_f - __dn, __first.__ctz_);
102 __storage_type __b = *__first.__seg_ & __m;
103 unsigned __clz_r = __bits_per_word - __result.__ctz_;
104 __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
105 __m = std::__middle_mask<__storage_type>(__clz_r - __ddn, __result.__ctz_);
106 *__result.__seg_ &= ~__m;
107 if (__result.__ctz_ > __first.__ctz_)
108 *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
109 else
110 *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
111 __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
112 __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
113 __dn -= __ddn;
114 if (__dn > 0) {
115 __m = std::__trailing_mask<__storage_type>(__bits_per_word - __dn);
116 *__result.__seg_ &= ~__m;
117 *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
118 __result.__ctz_ = static_cast<unsigned>(__dn);
119 }
120 ++__first.__seg_;
121 // __first.__ctz_ = 0;
122 }
123 // __first.__ctz_ == 0;
124 // do middle words
125 unsigned __clz_r = __bits_per_word - __result.__ctz_;
126 __storage_type __m = std::__leading_mask<__storage_type>(__result.__ctz_);
127 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) {
128 __storage_type __b = *__first.__seg_;
129 *__result.__seg_ &= ~__m;
130 *__result.__seg_ |= __b << __result.__ctz_;
131 ++__result.__seg_;
132 *__result.__seg_ &= __m;
133 *__result.__seg_ |= __b >> __clz_r;
134 }
135 // do last word
136 if (__n > 0) {
137 __m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
138 __storage_type __b = *__first.__seg_ & __m;
139 __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r));
140 __m = std::__middle_mask<__storage_type>(__clz_r - __dn, __result.__ctz_);
141 *__result.__seg_ &= ~__m;
142 *__result.__seg_ |= __b << __result.__ctz_;
143 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
144 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
145 __n -= __dn;
146 if (__n > 0) {
147 __m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
148 *__result.__seg_ &= ~__m;
149 *__result.__seg_ |= __b >> __dn;
150 __result.__ctz_ = static_cast<unsigned>(__n);
151 }
152 }
153 }
154 return __result;
155}
156
15740struct __copy_impl {
158 template <class _InIter, class _Sent, class _OutIter>
41 template <class _InIter,
42 class _Sent,
43 class _OutIter,
44 __enable_if_t<!__specialized_algorithm<_Algorithm::__copy,
45 __iterator_pair<_InIter, _Sent>,
46 __single_iterator<_OutIter> >::__has_algorithm,
47 int> = 0>
15948 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
16049 operator()(_InIter __first, _Sent __last, _OutIter __result) const {
16150 while (__first != __last) {
......@@ -167,37 +56,39 @@ struct __copy_impl {
16756 return std::make_pair(std::move(__first), std::move(__result));
16857 }
16958
170 template <class _InIter, class _OutIter>
171 struct _CopySegment {
172 using _Traits _LIBCPP_NODEBUG = __segmented_iterator_traits<_InIter>;
173
174 _OutIter& __result_;
175
176 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit _CopySegment(_OutIter& __result)
177 : __result_(__result) {}
178
179 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
180 operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
181 __result_ = std::__copy(__lfirst, __llast, std::move(__result_)).second;
182 }
183 };
59 template <class _InIter,
60 class _Sent,
61 class _OutIter,
62 __enable_if_t<__specialized_algorithm<_Algorithm::__copy,
63 __iterator_pair<_InIter, _Sent>,
64 __single_iterator<_OutIter> >::__has_algorithm,
65 int> = 0>
66 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static pair<_InIter, _OutIter>
67 operator()(_InIter __first, _Sent __last, _OutIter __result) {
68 return __specialized_algorithm<_Algorithm::__copy, __iterator_pair<_InIter, _Sent>, __single_iterator<_OutIter> >()(
69 std::move(__first), std::move(__last), std::move(__result));
70 }
18471
185 template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
72 template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
18673 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
18774 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
188 std::__for_each_segment(__first, __last, _CopySegment<_InIter, _OutIter>(__result));
75 using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
76 std::__for_each_segment(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
77 __result = std::__copy(std::move(__lfirst), std::move(__llast), std::move(__result)).second;
78 });
18979 return std::make_pair(__last, std::move(__result));
19080 }
19181
19282 template <class _InIter,
19383 class _OutIter,
19484 __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
195 !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
85 !__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>,
19686 int> = 0>
19787 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
19888 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
19989 using _Traits = __segmented_iterator_traits<_OutIter>;
200 using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
90 using _DiffT =
91 typename common_type<__iterator_difference_type<_InIter>, __iterator_difference_type<_OutIter> >::type;
20192
20293 if (__first == __last)
20394 return std::make_pair(std::move(__first), std::move(__result));
......@@ -217,16 +108,6 @@ struct __copy_impl {
217108 }
218109 }
219110
220 template <class _Cp, bool _IsConst>
221 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<__bit_iterator<_Cp, _IsConst>, __bit_iterator<_Cp, false> >
222 operator()(__bit_iterator<_Cp, _IsConst> __first,
223 __bit_iterator<_Cp, _IsConst> __last,
224 __bit_iterator<_Cp, false> __result) const {
225 if (__first.__ctz_ == __result.__ctz_)
226 return std::make_pair(__last, std::__copy_aligned(__first, __last, __result));
227 return std::make_pair(__last, std::__copy_unaligned(__first, __last, __result));
228 }
229
230111 // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
231112 template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
232113 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
lib/libcxx/include/__algorithm/copy_backward.h+9-24
......@@ -11,6 +11,7 @@
1111
1212#include <__algorithm/copy_move_common.h>
1313#include <__algorithm/copy_n.h>
14#include <__algorithm/for_each_segment.h>
1415#include <__algorithm/iterator_operations.h>
1516#include <__algorithm/min.h>
1617#include <__config>
......@@ -170,37 +171,20 @@ struct __copy_backward_impl {
170171 return std::make_pair(std::move(__original_last_iter), std::move(__result));
171172 }
172173
173 template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
174 template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
174175 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
175176 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
176 using _Traits = __segmented_iterator_traits<_InIter>;
177 auto __sfirst = _Traits::__segment(__first);
178 auto __slast = _Traits::__segment(__last);
179 if (__sfirst == __slast) {
180 auto __iters =
181 std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
182 return std::make_pair(__last, __iters.second);
183 }
184
185 __result =
186 std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
187 .second;
188 --__slast;
189 while (__sfirst != __slast) {
190 __result =
191 std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
192 .second;
193 --__slast;
194 }
195 __result = std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
196 .second;
177 using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
178 std::__for_each_segment_backward(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
179 __result = std::__copy_backward<_AlgPolicy>(std::move(__lfirst), std::move(__llast), std::move(__result)).second;
180 });
197181 return std::make_pair(__last, std::move(__result));
198182 }
199183
200184 template <class _InIter,
201185 class _OutIter,
202186 __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
203 !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
187 !__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>,
204188 int> = 0>
205189 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
206190 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
......@@ -214,7 +198,8 @@ struct __copy_backward_impl {
214198
215199 auto __local_last = _Traits::__local(__result);
216200 while (true) {
217 using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
201 using _DiffT =
202 typename common_type<__iterator_difference_type<_InIter>, __iterator_difference_type<_OutIter> >::type;
218203
219204 auto __local_first = _Traits::__begin(__segment_iterator);
220205 auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
lib/libcxx/include/__algorithm/copy_n.h+50-16
......@@ -10,31 +10,63 @@
1010#define _LIBCPP___ALGORITHM_COPY_N_H
1111
1212#include <__algorithm/copy.h>
13#include <__algorithm/iterator_operations.h>
1314#include <__config>
1415#include <__iterator/iterator_traits.h>
1516#include <__type_traits/enable_if.h>
1617#include <__utility/convert_to_integral.h>
18#include <__utility/move.h>
19#include <__utility/pair.h>
1720
1821#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1922# pragma GCC system_header
2023#endif
2124
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
2228_LIBCPP_BEGIN_NAMESPACE_STD
2329
30template <class _AlgPolicy,
31 class _InIter,
32 class _OutIter,
33 __enable_if_t<__has_random_access_iterator_category<_InIter>::value, int> = 0>
34_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
35__copy_n(_InIter __first, typename _IterOps<_AlgPolicy>::template __difference_type<_InIter> __n, _OutIter __result) {
36 return std::__copy(__first, __first + __n, std::move(__result));
37}
38
39template <class _AlgPolicy,
40 class _InIter,
41 class _OutIter,
42 __enable_if_t<!__has_random_access_iterator_category<_InIter>::value, int> = 0>
43_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
44__copy_n(_InIter __first, typename _IterOps<_AlgPolicy>::template __difference_type<_InIter> __n, _OutIter __result) {
45 while (__n != 0) {
46 *__result = *__first;
47 ++__first;
48 ++__result;
49 --__n;
50 }
51 return std::make_pair(std::move(__first), std::move(__result));
52}
53
54// The InputIterator case is handled specially here because it's been written in a way to avoid incrementing __first
55// if not absolutely required. This was done to allow its use with istream_iterator and we want to avoid breaking
56// people, at least currently.
57// See https://github.com/llvm/llvm-project/commit/99847d2bf132854fffa019bab19818768102ccad
2458template <class _InputIterator,
2559 class _Size,
2660 class _OutputIterator,
27 __enable_if_t<__has_input_iterator_category<_InputIterator>::value &&
28 !__has_random_access_iterator_category<_InputIterator>::value,
29 int> = 0>
30inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
31copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
32 typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
33 _IntegralSize __n = __orig_n;
34 if (__n > 0) {
61 __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
62_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
63copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) {
64 using _IntegralSize = decltype(std::__convert_to_integral(__n));
65 _IntegralSize __converted = __n;
66 if (__converted > 0) {
3567 *__result = *__first;
3668 ++__result;
37 for (--__n; __n > 0; --__n) {
69 for (--__converted; __converted > 0; --__converted) {
3870 ++__first;
3971 *__result = *__first;
4072 ++__result;
......@@ -46,15 +78,17 @@ copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
4678template <class _InputIterator,
4779 class _Size,
4880 class _OutputIterator,
49 __enable_if_t<__has_random_access_iterator_category<_InputIterator>::value, int> = 0>
50inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
51copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
52 typedef typename iterator_traits<_InputIterator>::difference_type difference_type;
53 typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
54 _IntegralSize __n = __orig_n;
55 return std::copy(__first, __first + difference_type(__n), __result);
81 __enable_if_t<!__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
82_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
83copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) {
84 using _IntegralSize = decltype(std::__convert_to_integral(__n));
85 _IntegralSize __converted = __n;
86 return std::__copy_n<_ClassicAlgPolicy>(__first, __iterator_difference_type<_InputIterator>(__converted), __result)
87 .second;
5688}
5789
5890_LIBCPP_END_NAMESPACE_STD
5991
92_LIBCPP_POP_MACROS
93
6094#endif // _LIBCPP___ALGORITHM_COPY_N_H
lib/libcxx/include/__algorithm/count.h+2-2
......@@ -72,7 +72,7 @@ __count_bool(__bit_iterator<_Cp, _IsConst> __first, typename __size_difference_t
7272}
7373
7474template <class, class _Cp, bool _IsConst, class _Tp, class _Proj, __enable_if_t<__is_identity<_Proj>::value, int> = 0>
75_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<__bit_iterator<_Cp, _IsConst> >
75_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iterator_difference_type<__bit_iterator<_Cp, _IsConst> >
7676__count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value, _Proj&) {
7777 if (__value)
7878 return std::__count_bool<true>(
......@@ -82,7 +82,7 @@ __count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __l
8282}
8383
8484template <class _InputIterator, class _Tp>
85[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<_InputIterator>
85[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iterator_difference_type<_InputIterator>
8686count(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
8787 __identity __proj;
8888 return std::__count<_ClassicAlgPolicy>(__first, __last, __value, __proj);
lib/libcxx/include/__algorithm/equal.h+43-55
......@@ -160,22 +160,28 @@ template <class _Cp,
160160 bool _IsConst1,
161161 bool _IsConst2,
162162 class _BinaryPredicate,
163 __enable_if_t<__desugars_to_v<__equal_tag, _BinaryPredicate, bool, bool>, int> = 0>
163 class _Proj1,
164 class _Proj2,
165 __enable_if_t<__is_identity<_Proj1>::value && __is_identity<_Proj2>::value &&
166 __desugars_to_v<__equal_tag, _BinaryPredicate, bool, bool>,
167 int> = 0>
164168[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(
165169 __bit_iterator<_Cp, _IsConst1> __first1,
166170 __bit_iterator<_Cp, _IsConst1> __last1,
167171 __bit_iterator<_Cp, _IsConst2> __first2,
168 _BinaryPredicate) {
172 _BinaryPredicate,
173 _Proj1&,
174 _Proj2&) {
169175 if (__first1.__ctz_ == __first2.__ctz_)
170176 return std::__equal_aligned(__first1, __last1, __first2);
171177 return std::__equal_unaligned(__first1, __last1, __first2);
172178}
173179
174template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
180template <class _InIter1, class _Sent1, class _InIter2, class _Pred, class _Proj1, class _Proj2>
175181[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(
176 _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate& __pred) {
182 _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
177183 for (; __first1 != __last1; ++__first1, (void)++__first2)
178 if (!__pred(*__first1, *__first2))
184 if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
179185 return false;
180186 return true;
181187}
......@@ -183,19 +189,23 @@ template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
183189template <class _Tp,
184190 class _Up,
185191 class _BinaryPredicate,
186 __enable_if_t<__desugars_to_v<__equal_tag, _BinaryPredicate, _Tp, _Up> && !is_volatile<_Tp>::value &&
187 !is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
192 class _Proj1,
193 class _Proj2,
194 __enable_if_t<__is_identity<_Proj1>::value && __is_identity<_Proj2>::value &&
195 __desugars_to_v<__equal_tag, _BinaryPredicate, _Tp, _Up> && !is_volatile<_Tp>::value &&
196 !is_volatile<_Up>::value && __is_trivially_equality_comparable_v<_Tp, _Up>,
188197 int> = 0>
189198[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
190__equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) {
199__equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&, _Proj1&, _Proj2&) {
191200 return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
192201}
193202
194203template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
195204[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
196205equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
206 __identity __proj;
197207 return std::__equal_iter_impl(
198 std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred);
208 std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred, __proj, __proj);
199209}
200210
201211template <class _InputIterator1, class _InputIterator2>
......@@ -206,52 +216,28 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first
206216
207217#if _LIBCPP_STD_VER >= 14
208218
209template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
210[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
211 _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __comp, _Proj1& __proj1, _Proj2& __proj2) {
212 while (__first1 != __last1 && __first2 != __last2) {
213 if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
214 return false;
215 ++__first1;
216 ++__first2;
217 }
218 return __first1 == __last1 && __first2 == __last2;
219}
220
221template <class _Tp,
222 class _Up,
223 class _Pred,
224 class _Proj1,
225 class _Proj2,
226 __enable_if_t<__desugars_to_v<__equal_tag, _Pred, _Tp, _Up> && __is_identity<_Proj1>::value &&
227 __is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value &&
228 __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
229 int> = 0>
230[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
231__equal_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) {
232 return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
233}
234
235template <class _Cp,
236 bool _IsConst1,
237 bool _IsConst2,
219template <bool __known_equal_length,
220 class _Iter1,
221 class _Sent1,
222 class _Iter2,
223 class _Sent2,
238224 class _Pred,
239225 class _Proj1,
240 class _Proj2,
241 __enable_if_t<__desugars_to_v<__equal_tag, _Pred, bool, bool> && __is_identity<_Proj1>::value &&
242 __is_identity<_Proj2>::value,
243 int> = 0>
226 class _Proj2>
244227[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
245 __bit_iterator<_Cp, _IsConst1> __first1,
246 __bit_iterator<_Cp, _IsConst1> __last1,
247 __bit_iterator<_Cp, _IsConst2> __first2,
248 __bit_iterator<_Cp, _IsConst2>,
249 _Pred&,
250 _Proj1&,
251 _Proj2&) {
252 if (__first1.__ctz_ == __first2.__ctz_)
253 return std::__equal_aligned(__first1, __last1, __first2);
254 return std::__equal_unaligned(__first1, __last1, __first2);
228 _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __comp, _Proj1& __proj1, _Proj2& __proj2) {
229 if constexpr (__known_equal_length) {
230 return std::__equal_iter_impl(
231 std::move(__first1), std::move(__last1), std::move(__first2), __comp, __proj1, __proj2);
232 } else {
233 while (__first1 != __last1 && __first2 != __last2) {
234 if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
235 return false;
236 ++__first1;
237 ++__first2;
238 }
239 return __first1 == __last1 && __first2 == __last2;
240 }
255241}
256242
257243template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
......@@ -261,13 +247,15 @@ equal(_InputIterator1 __first1,
261247 _InputIterator2 __first2,
262248 _InputIterator2 __last2,
263249 _BinaryPredicate __pred) {
264 if constexpr (__has_random_access_iterator_category<_InputIterator1>::value &&
265 __has_random_access_iterator_category<_InputIterator2>::value) {
250 static constexpr bool __both_random_access =
251 __has_random_access_iterator_category<_InputIterator1>::value &&
252 __has_random_access_iterator_category<_InputIterator2>::value;
253 if constexpr (__both_random_access) {
266254 if (std::distance(__first1, __last1) != std::distance(__first2, __last2))
267255 return false;
268256 }
269257 __identity __proj;
270 return std::__equal_impl(
258 return std::__equal_impl<__both_random_access>(
271259 std::__unwrap_iter(__first1),
272260 std::__unwrap_iter(__last1),
273261 std::__unwrap_iter(__first2),
lib/libcxx/include/__algorithm/fill.h+26-8
......@@ -10,8 +10,12 @@
1010#define _LIBCPP___ALGORITHM_FILL_H
1111
1212#include <__algorithm/fill_n.h>
13#include <__algorithm/for_each_segment.h>
1314#include <__config>
1415#include <__iterator/iterator_traits.h>
16#include <__iterator/segmented_iterator.h>
17#include <__type_traits/enable_if.h>
18#include <__type_traits/is_same.h>
1519
1620#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1721# pragma GCC system_header
......@@ -21,23 +25,37 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2125
2226// fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
2327
24template <class _ForwardIterator, class _Tp>
25inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
26__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, forward_iterator_tag) {
28template <class _ForwardIterator, class _Sentinel, class _Tp>
29inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
30__fill(_ForwardIterator __first, _Sentinel __last, const _Tp& __value) {
31#ifndef _LIBCPP_CXX03_LANG
32 if constexpr (is_same<_ForwardIterator, _Sentinel>::value && __is_segmented_iterator_v<_ForwardIterator>) {
33 using __local_iterator_t = typename __segmented_iterator_traits<_ForwardIterator>::__local_iterator;
34 std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
35 std::__fill(__lfirst, __llast, __value);
36 });
37 return __last;
38 }
39#endif
2740 for (; __first != __last; ++__first)
2841 *__first = __value;
42 return __first;
2943}
3044
31template <class _RandomAccessIterator, class _Tp>
32inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
33__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, random_access_iterator_tag) {
34 std::fill_n(__first, __last - __first, __value);
45template <class _RandomAccessIterator,
46 class _Tp,
47 __enable_if_t<__has_random_access_iterator_category<_RandomAccessIterator>::value &&
48 !__is_segmented_iterator_v<_RandomAccessIterator>,
49 int> = 0>
50inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
51__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value) {
52 return std::__fill_n(__first, __last - __first, __value);
3553}
3654
3755template <class _ForwardIterator, class _Tp>
3856inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
3957fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
40 std::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category());
58 std::__fill(__first, __last, __value);
4159}
4260
4361_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/fill_n.h+32-46
......@@ -9,11 +9,14 @@
99#ifndef _LIBCPP___ALGORITHM_FILL_N_H
1010#define _LIBCPP___ALGORITHM_FILL_N_H
1111
12#include <__algorithm/min.h>
12#include <__algorithm/for_each_n_segment.h>
13#include <__algorithm/specialized_algorithms.h>
1314#include <__config>
14#include <__fwd/bit_reference.h>
15#include <__memory/pointer_traits.h>
15#include <__iterator/iterator_traits.h>
16#include <__iterator/segmented_iterator.h>
17#include <__type_traits/enable_if.h>
1618#include <__utility/convert_to_integral.h>
19#include <__utility/move.h>
1720
1821#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1922# pragma GCC system_header
......@@ -26,56 +29,39 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2629
2730// fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
2831
29template <class _OutputIterator, class _Size, class _Tp>
30inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
31__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value);
32
33template <bool _FillVal, class _Cp>
34_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
35__fill_n_bool(__bit_iterator<_Cp, false> __first, typename __size_difference_type_traits<_Cp>::size_type __n) {
36 using _It = __bit_iterator<_Cp, false>;
37 using __storage_type = typename _It::__storage_type;
38
39 const int __bits_per_word = _It::__bits_per_word;
40 // do first partial word
41 if (__first.__ctz_ != 0) {
42 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
43 __storage_type __dn = std::min(__clz_f, __n);
44 std::__fill_masked_range(std::__to_address(__first.__seg_), __clz_f - __dn, __first.__ctz_, _FillVal);
45 __n -= __dn;
46 ++__first.__seg_;
47 }
48 // do middle whole words
49 __storage_type __nw = __n / __bits_per_word;
50 std::__fill_n(std::__to_address(__first.__seg_), __nw, _FillVal ? static_cast<__storage_type>(-1) : 0);
51 __n -= __nw * __bits_per_word;
52 // do last partial word
53 if (__n > 0) {
54 __first.__seg_ += __nw;
55 std::__fill_masked_range(std::__to_address(__first.__seg_), __bits_per_word - __n, 0u, _FillVal);
56 }
57}
58
59template <class _Cp, class _Size>
60inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false>
61__fill_n(__bit_iterator<_Cp, false> __first, _Size __n, const bool& __value) {
62 if (__n > 0) {
63 if (__value)
64 std::__fill_n_bool<true>(__first, __n);
65 else
66 std::__fill_n_bool<false>(__first, __n);
67 }
68 return __first + __n;
69}
70
71template <class _OutputIterator, class _Size, class _Tp>
32template <
33 class _OutputIterator,
34 class _Size,
35 class _Tp,
36 __enable_if_t<!__specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutputIterator> >::__has_algorithm,
37 int> = 0>
7238inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
7339__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
40#ifndef _LIBCPP_CXX03_LANG
41 if constexpr (__is_segmented_iterator_v<_OutputIterator>) {
42 using __local_iterator = typename __segmented_iterator_traits<_OutputIterator>::__local_iterator;
43 if constexpr (__has_random_access_iterator_category<__local_iterator>::value) {
44 return std::__for_each_n_segment(__first, __n, [&](__local_iterator __lfirst, __local_iterator __llast) {
45 std::__fill_n(__lfirst, __llast - __lfirst, __value);
46 });
47 }
48 }
49#endif
7450 for (; __n > 0; ++__first, (void)--__n)
7551 *__first = __value;
7652 return __first;
7753}
7854
55template <class _OutIter,
56 class _Size,
57 class _Tp,
58 __enable_if_t<__specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutIter> >::__has_algorithm,
59 int> = 0>
60_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutIter __fill_n(_OutIter __first, _Size __n, const _Tp& __value) {
61 return __specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutIter> >()(
62 std::move(__first), __n, __value);
63}
64
7965template <class _OutputIterator, class _Size, class _Tp>
8066inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
8167fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
lib/libcxx/include/__algorithm/find.h+96-39
......@@ -12,16 +12,19 @@
1212
1313#include <__algorithm/find_segment_if.h>
1414#include <__algorithm/min.h>
15#include <__algorithm/simd_utils.h>
1516#include <__algorithm/unwrap_iter.h>
1617#include <__bit/countr.h>
1718#include <__bit/invert_if.h>
1819#include <__config>
20#include <__cstddef/size_t.h>
1921#include <__functional/identity.h>
2022#include <__fwd/bit_reference.h>
2123#include <__iterator/segmented_iterator.h>
2224#include <__string/constexpr_c_functions.h>
2325#include <__type_traits/enable_if.h>
2426#include <__type_traits/invoke.h>
27#include <__type_traits/is_constant_evaluated.h>
2528#include <__type_traits/is_equality_comparable.h>
2629#include <__type_traits/is_integral.h>
2730#include <__type_traits/is_signed.h>
......@@ -44,46 +47,108 @@ _LIBCPP_BEGIN_NAMESPACE_STD
4447// generic implementation
4548template <class _Iter, class _Sent, class _Tp, class _Proj>
4649_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
47__find(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
50__find_loop(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
4851 for (; __first != __last; ++__first)
4952 if (std::__invoke(__proj, *__first) == __value)
5053 break;
5154 return __first;
5255}
5356
54// trivially equality comparable implementations
55template <class _Tp,
56 class _Up,
57 class _Proj,
58 __enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
59 sizeof(_Tp) == 1,
60 int> = 0>
61_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
62 if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first))
63 return __ret;
64 return __last;
57template <class _Iter, class _Sent, class _Tp, class _Proj>
58_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
59__find(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
60 return std::__find_loop(std::move(__first), std::move(__last), __value, __proj);
6561}
6662
67#if _LIBCPP_HAS_WIDE_CHARACTERS
63#if _LIBCPP_VECTORIZE_ALGORITHMS
64template <class _Tp, class _Up>
65[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
66_LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find_vectorized(_Tp* __first, _Tp* __last, _Up __value) {
67 if (!__libcpp_is_constant_evaluated()) {
68 constexpr size_t __unroll_count = 4;
69 constexpr size_t __vec_size = __native_vector_size<_Tp>;
70 using __vec = __simd_vector<_Tp, __vec_size>;
71
72 auto __orig_first = __first;
73
74 auto __values = static_cast<__simd_vector<_Tp, __vec_size>>(__value); // broadcast the value
75 while (static_cast<size_t>(__last - __first) >= __unroll_count * __vec_size) [[__unlikely__]] {
76 __vec __lhs[__unroll_count];
77
78 for (size_t __i = 0; __i != __unroll_count; ++__i)
79 __lhs[__i] = std::__load_vector<__vec>(__first + __i * __vec_size);
80
81 for (size_t __i = 0; __i != __unroll_count; ++__i) {
82 if (auto __cmp_res = __lhs[__i] == __values; std::__any_of(__cmp_res)) {
83 auto __offset = __i * __vec_size + std::__find_first_set(__cmp_res);
84 return __first + __offset;
85 }
86 }
87
88 __first += __unroll_count * __vec_size;
89 }
90
91 // check the remaining 0-3 vectors
92 while (static_cast<size_t>(__last - __first) >= __vec_size) {
93 if (auto __cmp_res = std::__load_vector<__vec>(__first) == __values; std::__any_of(__cmp_res)) {
94 return __first + std::__find_first_set(__cmp_res);
95 }
96 __first += __vec_size;
97 }
98
99 if (__last - __first == 0)
100 return __first;
101
102 // Check if we can load elements in front of the current pointer. If that's the case load a vector at
103 // (last - vector_size) to check the remaining elements
104 if (static_cast<size_t>(__first - __orig_first) >= __vec_size) {
105 __first = __last - __vec_size;
106 return __first + std::__find_first_set(std::__load_vector<__vec>(__first) == __values);
107 }
108 }
109
110 __identity __proj;
111 return std::__find_loop(__first, __last, __value, __proj);
112}
113#endif
114
115#ifndef _LIBCPP_CXX03_LANG
116// trivially equality comparable implementations
68117template <class _Tp,
69118 class _Up,
70119 class _Proj,
71 __enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
72 sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t),
73 int> = 0>
120 __enable_if_t<__is_identity<_Proj>::value && __is_trivially_equality_comparable_v<_Tp, _Up>, int> = 0>
74121_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
75 if (auto __ret = std::__constexpr_wmemchr(__first, __value, __last - __first))
76 return __ret;
77 return __last;
122 if constexpr (sizeof(_Tp) == 1) {
123 if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first))
124 return __ret;
125 return __last;
126 }
127# if _LIBCPP_HAS_WIDE_CHARACTERS
128 else if constexpr (sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t)) {
129 if (auto __ret = std::__constexpr_wmemchr(__first, __value, __last - __first))
130 return __ret;
131 return __last;
132 }
133# endif
134# if _LIBCPP_VECTORIZE_ALGORITHMS
135 else if constexpr (is_integral<_Tp>::value) {
136 return std::__find_vectorized(__first, __last, __value);
137 }
138# endif
139 else {
140 __identity __proj;
141 return std::__find_loop(__first, __last, __value, __proj);
142 }
78143}
79#endif // _LIBCPP_HAS_WIDE_CHARACTERS
144#endif
80145
81146// TODO: This should also be possible to get right with different signedness
82147// cast integral types to allow vectorization
83148template <class _Tp,
84149 class _Up,
85150 class _Proj,
86 __enable_if_t<__is_identity<_Proj>::value && !__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
151 __enable_if_t<__is_identity<_Proj>::value && !__is_trivially_equality_comparable_v<_Tp, _Up> &&
87152 is_integral<_Tp>::value && is_integral<_Up>::value &&
88153 is_signed<_Tp>::value == is_signed<_Up>::value,
89154 int> = 0>
......@@ -143,31 +208,23 @@ __find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __la
143208
144209// segmented iterator implementation
145210
146template <class>
147struct __find_segment;
148
149211template <class _SegmentedIterator,
150212 class _Tp,
151213 class _Proj,
152 __enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
214 __enable_if_t<__is_segmented_iterator_v<_SegmentedIterator>, int> = 0>
153215_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator
154216__find(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value, _Proj& __proj) {
155 return std::__find_segment_if(std::move(__first), std::move(__last), __find_segment<_Tp>(__value), __proj);
217 using __local_iterator = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator;
218 return std::__find_segment_if(
219 std::move(__first),
220 std::move(__last),
221 [&__value](__local_iterator __lfirst, __local_iterator __llast, _Proj& __lproj) {
222 return std::__rewrap_iter(
223 __lfirst, std::__find(std::__unwrap_iter(__lfirst), std::__unwrap_iter(__llast), __value, __lproj));
224 },
225 __proj);
156226}
157227
158template <class _Tp>
159struct __find_segment {
160 const _Tp& __value_;
161
162 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __find_segment(const _Tp& __value) : __value_(__value) {}
163
164 template <class _InputIterator, class _Proj>
165 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _InputIterator
166 operator()(_InputIterator __first, _InputIterator __last, _Proj& __proj) const {
167 return std::__find(__first, __last, __value_, __proj);
168 }
169};
170
171228// public API
172229template <class _InputIterator, class _Tp>
173230[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
lib/libcxx/include/__algorithm/find_end.h+105
......@@ -76,6 +76,111 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1>
7676 }
7777}
7878
79template <class _AlgPolicy,
80 class _Pred,
81 class _Iter1,
82 class _Sent1,
83 class _Iter2,
84 class _Sent2,
85 class _Proj1,
86 class _Proj2>
87_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter1> __find_end_impl(
88 _Iter1 __first1,
89 _Sent1 __sent1,
90 _Iter2 __first2,
91 _Sent2 __sent2,
92 _Pred& __pred,
93 _Proj1& __proj1,
94 _Proj2& __proj2,
95 bidirectional_iterator_tag,
96 bidirectional_iterator_tag) {
97 auto __last1 = _IterOps<_AlgPolicy>::next(__first1, __sent1);
98 auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __sent2);
99 // modeled after search algorithm (in reverse)
100 if (__first2 == __last2)
101 return std::make_pair(__last1, __last1); // Everything matches an empty sequence
102 _Iter1 __l1 = __last1;
103 _Iter2 __l2 = __last2;
104 --__l2;
105 while (true) {
106 // Find last element in sequence 1 that matches *(__last2-1), with a mininum of loop checks
107 while (true) {
108 if (__first1 == __l1) // return __last1 if no element matches *__first2
109 return std::make_pair(__last1, __last1);
110 if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
111 break;
112 }
113 // *__l1 matches *__l2, now match elements before here
114 _Iter1 __match_last = __l1;
115 _Iter1 __m1 = __l1;
116 _Iter2 __m2 = __l2;
117 while (true) {
118 if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern)
119 return std::make_pair(__m1, ++__match_last);
120 if (__m1 == __first1) // Otherwise if source exhaused, pattern not found
121 return std::make_pair(__last1, __last1);
122
123 // if there is a mismatch, restart with a new __l1
124 if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) {
125 break;
126 } // else there is a match, check next elements
127 }
128 }
129}
130
131template <class _AlgPolicy,
132 class _Pred,
133 class _Iter1,
134 class _Sent1,
135 class _Iter2,
136 class _Sent2,
137 class _Proj1,
138 class _Proj2>
139_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __find_end_impl(
140 _Iter1 __first1,
141 _Sent1 __sent1,
142 _Iter2 __first2,
143 _Sent2 __sent2,
144 _Pred& __pred,
145 _Proj1& __proj1,
146 _Proj2& __proj2,
147 random_access_iterator_tag,
148 random_access_iterator_tag) {
149 typedef typename iterator_traits<_Iter1>::difference_type _D1;
150 auto __last1 = _IterOps<_AlgPolicy>::next(__first1, __sent1);
151 auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __sent2);
152 // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
153 auto __len2 = __last2 - __first2;
154 if (__len2 == 0)
155 return std::make_pair(__last1, __last1);
156 auto __len1 = __last1 - __first1;
157 if (__len1 < __len2)
158 return std::make_pair(__last1, __last1);
159 const _Iter1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here
160 _Iter1 __l1 = __last1;
161 _Iter2 __l2 = __last2;
162 --__l2;
163 while (true) {
164 while (true) {
165 if (__s == __l1)
166 return std::make_pair(__last1, __last1);
167 if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
168 break;
169 }
170 _Iter1 __last_match = __l1;
171 _Iter1 __m1 = __l1;
172 _Iter2 __m2 = __l2;
173 while (true) {
174 if (__m2 == __first2)
175 return std::make_pair(__m1, ++__last_match);
176 // no need to check range on __m1 because __s guarantees we have enough source
177 if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) {
178 break;
179 }
180 }
181 }
182}
183
79184template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
80185[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_end_classic(
81186 _ForwardIterator1 __first1,
lib/libcxx/include/__algorithm/for_each.h+18-24
......@@ -11,45 +11,41 @@
1111#define _LIBCPP___ALGORITHM_FOR_EACH_H
1212
1313#include <__algorithm/for_each_segment.h>
14#include <__algorithm/specialized_algorithms.h>
1415#include <__config>
1516#include <__functional/identity.h>
1617#include <__iterator/segmented_iterator.h>
17#include <__type_traits/enable_if.h>
1818#include <__type_traits/invoke.h>
19#include <__utility/move.h>
19#include <__type_traits/is_same.h>
2020
2121#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2222# pragma GCC system_header
2323#endif
2424
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
2825_LIBCPP_BEGIN_NAMESPACE_STD
2926
3027template <class _InputIterator, class _Sent, class _Func, class _Proj>
3128_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
32__for_each(_InputIterator __first, _Sent __last, _Func& __f, _Proj& __proj) {
29__for_each(_InputIterator __first, _Sent __last, _Func& __func, _Proj& __proj) {
30#ifndef _LIBCPP_CXX03_LANG
31 if constexpr (using _SpecialAlg =
32 __specialized_algorithm<_Algorithm::__for_each, __iterator_pair<_InputIterator, _Sent>>;
33 _SpecialAlg::__has_algorithm) {
34 _SpecialAlg()(__first, __last, __func, __proj);
35 return __last;
36 } else if constexpr (is_same<_InputIterator, _Sent>::value && __is_segmented_iterator_v<_InputIterator>) {
37 using __local_iterator_t = typename __segmented_iterator_traits<_InputIterator>::__local_iterator;
38 std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
39 std::__for_each(__lfirst, __llast, __func, __proj);
40 });
41 return __last;
42 }
43#endif
3344 for (; __first != __last; ++__first)
34 std::__invoke(__f, std::__invoke(__proj, *__first));
45 std::__invoke(__func, std::__invoke(__proj, *__first));
3546 return __first;
3647}
3748
38#ifndef _LIBCPP_CXX03_LANG
39template <class _SegmentedIterator,
40 class _Func,
41 class _Proj,
42 __enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
43_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _SegmentedIterator
44__for_each(_SegmentedIterator __first, _SegmentedIterator __last, _Func& __func, _Proj& __proj) {
45 using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator;
46 std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
47 std::__for_each(__lfirst, __llast, __func, __proj);
48 });
49 return __last;
50}
51#endif // !_LIBCPP_CXX03_LANG
52
5349template <class _InputIterator, class _Func>
5450_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Func
5551for_each(_InputIterator __first, _InputIterator __last, _Func __f) {
......@@ -60,6 +56,4 @@ for_each(_InputIterator __first, _InputIterator __last, _Func __f) {
6056
6157_LIBCPP_END_NAMESPACE_STD
6258
63_LIBCPP_POP_MACROS
64
6559#endif // _LIBCPP___ALGORITHM_FOR_EACH_H
lib/libcxx/include/__algorithm/for_each_n.h+20-47
......@@ -16,10 +16,7 @@
1616#include <__functional/identity.h>
1717#include <__iterator/iterator_traits.h>
1818#include <__iterator/segmented_iterator.h>
19#include <__type_traits/disjunction.h>
20#include <__type_traits/enable_if.h>
2119#include <__type_traits/invoke.h>
22#include <__type_traits/negation.h>
2320#include <__utility/convert_to_integral.h>
2421#include <__utility/move.h>
2522
......@@ -32,57 +29,33 @@ _LIBCPP_PUSH_MACROS
3229
3330_LIBCPP_BEGIN_NAMESPACE_STD
3431
35template <class _InputIterator,
36 class _Size,
37 class _Func,
38 class _Proj,
39 __enable_if_t<!__has_random_access_iterator_category<_InputIterator>::value &&
40 _Or< _Not<__is_segmented_iterator<_InputIterator> >,
41 _Not<__has_random_access_local_iterator<_InputIterator> > >::value,
42 int> = 0>
32template <class _InputIterator, class _Size, class _Func, class _Proj>
4333_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
4434__for_each_n(_InputIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
4535 typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
4636 _IntegralSize __n = __orig_n;
47 while (__n > 0) {
48 std::__invoke(__f, std::__invoke(__proj, *__first));
49 ++__first;
50 --__n;
51 }
52 return std::move(__first);
53}
54
55template <class _RandIter,
56 class _Size,
57 class _Func,
58 class _Proj,
59 __enable_if_t<__has_random_access_iterator_category<_RandIter>::value, int> = 0>
60_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandIter
61__for_each_n(_RandIter __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
62 typename std::iterator_traits<_RandIter>::difference_type __n = __orig_n;
63 auto __last = __first + __n;
64 std::__for_each(__first, __last, __f, __proj);
65 return __last;
66}
6737
6838#ifndef _LIBCPP_CXX03_LANG
69template <class _SegmentedIterator,
70 class _Size,
71 class _Func,
72 class _Proj,
73 __enable_if_t<!__has_random_access_iterator_category<_SegmentedIterator>::value &&
74 __is_segmented_iterator<_SegmentedIterator>::value &&
75 __has_random_access_iterator_category<
76 typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value,
77 int> = 0>
78_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _SegmentedIterator
79__for_each_n(_SegmentedIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
80 using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator;
81 return std::__for_each_n_segment(__first, __orig_n, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
82 std::__for_each(__lfirst, __llast, __f, __proj);
83 });
39 if constexpr (__is_segmented_iterator_v<_InputIterator>) {
40 using __local_iterator = typename __segmented_iterator_traits<_InputIterator>::__local_iterator;
41 if constexpr (__has_random_access_iterator_category<__local_iterator>::value) {
42 return std::__for_each_n_segment(__first, __orig_n, [&](__local_iterator __lfirst, __local_iterator __llast) {
43 std::__for_each(__lfirst, __llast, __f, __proj);
44 });
45 } else {
46 return std::__for_each(__first, __first + __n, __f, __proj);
47 }
48 } else
49#endif
50 {
51 while (__n > 0) {
52 std::__invoke(__f, std::__invoke(__proj, *__first));
53 ++__first;
54 --__n;
55 }
56 return std::move(__first);
57 }
8458}
85#endif // !_LIBCPP_CXX03_LANG
8659
8760#if _LIBCPP_STD_VER >= 17
8861
lib/libcxx/include/__algorithm/for_each_n_segment.h+1-1
......@@ -27,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2727template <class _SegmentedIterator, class _Size, class _Functor>
2828_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator
2929__for_each_n_segment(_SegmentedIterator __first, _Size __orig_n, _Functor __func) {
30 static_assert(__is_segmented_iterator<_SegmentedIterator>::value &&
30 static_assert(__is_segmented_iterator_v<_SegmentedIterator> &&
3131 __has_random_access_iterator_category<
3232 typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value,
3333 "__for_each_n_segment only works with segmented iterators with random-access local iterators");
lib/libcxx/include/__algorithm/for_each_segment.h+26
......@@ -48,6 +48,32 @@ __for_each_segment(_SegmentedIterator __first, _SegmentedIterator __last, _Funct
4848 __func(_Traits::__begin(__sfirst), _Traits::__local(__last));
4949}
5050
51template <class _SegmentedIterator, class _Functor>
52_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
53__for_each_segment_backward(_SegmentedIterator __first, _SegmentedIterator __last, _Functor __func) {
54 using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
55
56 auto __sfirst = _Traits::__segment(__first);
57 auto __slast = _Traits::__segment(__last);
58
59 // We are in a single segment, so we might not be at the beginning or end
60 if (__sfirst == __slast) {
61 __func(_Traits::__local(__first), _Traits::__local(__last));
62 return;
63 }
64
65 // We have more than one segment. Iterate over the last segment, since we might not start at the end
66 __func(_Traits::__begin(__slast), _Traits::__local(__last));
67 --__slast;
68 // iterate over the segments which are guaranteed to be completely in the range
69 while (__sfirst != __slast) {
70 __func(_Traits::__begin(__slast), _Traits::__end(__slast));
71 --__slast;
72 }
73 // iterate over the first segment
74 __func(_Traits::__local(__first), _Traits::__end(__slast));
75}
76
5177_LIBCPP_END_NAMESPACE_STD
5278
5379#endif // _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
lib/libcxx/include/__algorithm/generate.h+4-2
......@@ -9,7 +9,9 @@
99#ifndef _LIBCPP___ALGORITHM_GENERATE_H
1010#define _LIBCPP___ALGORITHM_GENERATE_H
1111
12#include <__algorithm/for_each.h>
1213#include <__config>
14#include <__utility/forward.h>
1315
1416#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1517# pragma GCC system_header
......@@ -20,8 +22,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2022template <class _ForwardIterator, class _Generator>
2123inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
2224generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
23 for (; __first != __last; ++__first)
24 *__first = __gen();
25 using __iter_ref = decltype(*__first);
26 std::for_each(__first, __last, [&](__iter_ref __element) { std::forward<__iter_ref>(__element) = __gen(); });
2527}
2628
2729_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/generate_n.h+19-6
......@@ -9,25 +9,38 @@
99#ifndef _LIBCPP___ALGORITHM_GENERATE_N_H
1010#define _LIBCPP___ALGORITHM_GENERATE_N_H
1111
12#include <__algorithm/for_each_n.h>
1213#include <__config>
13#include <__utility/convert_to_integral.h>
14#include <__functional/identity.h>
15#include <__utility/forward.h>
16#include <__utility/move.h>
1417
1518#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1619# pragma GCC system_header
1720#endif
1821
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
1925_LIBCPP_BEGIN_NAMESPACE_STD
2026
27template <class _OutputIterator, class _Size, class _Generator>
28inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
29__generate_n(_OutputIterator __first, _Size __orig_n, _Generator& __gen) {
30 using __iter_ref = decltype(*__first);
31 __identity __proj;
32 auto __f = [&](__iter_ref __element) { std::forward<__iter_ref>(__element) = __gen(); };
33 return std::__for_each_n(std::move(__first), __orig_n, __f, __proj);
34}
35
2136template <class _OutputIterator, class _Size, class _Generator>
2237inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
2338generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) {
24 typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
25 _IntegralSize __n = __orig_n;
26 for (; __n > 0; ++__first, (void)--__n)
27 *__first = __gen();
28 return __first;
39 return std::__generate_n(std::move(__first), __orig_n, __gen);
2940}
3041
3142_LIBCPP_END_NAMESPACE_STD
3243
44_LIBCPP_POP_MACROS
45
3346#endif // _LIBCPP___ALGORITHM_GENERATE_N_H
lib/libcxx/include/__algorithm/is_permutation.h+4-4
......@@ -78,7 +78,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation_impl(
7878 _Pred&& __pred,
7979 _Proj1&& __proj1,
8080 _Proj2&& __proj2) {
81 using _D1 = __iter_diff_t<_Iter1>;
81 using _D1 = __iterator_difference_type<_Iter1>;
8282
8383 for (auto __i = __first1; __i != __last1; ++__i) {
8484 // Have we already counted the number of *__i in [f1, l1)?
......@@ -126,7 +126,7 @@ template <class _AlgPolicy, class _ForwardIterator1, class _Sentinel1, class _Fo
126126 return true;
127127
128128 // __first1 != __last1 && *__first1 != *__first2
129 using _D1 = __iter_diff_t<_ForwardIterator1>;
129 using _D1 = __iterator_difference_type<_ForwardIterator1>;
130130 _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1);
131131 if (__l1 == _D1(1))
132132 return false;
......@@ -173,10 +173,10 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation(
173173 if (__first2 == __last2) // Second range is shorter
174174 return false;
175175
176 using _D1 = __iter_diff_t<_Iter1>;
176 using _D1 = __iterator_difference_type<_Iter1>;
177177 _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1);
178178
179 using _D2 = __iter_diff_t<_Iter2>;
179 using _D2 = __iterator_difference_type<_Iter2>;
180180 _D2 __l2 = _IterOps<_AlgPolicy>::distance(__first2, __last2);
181181 if (__l1 != __l2)
182182 return false;
lib/libcxx/include/__algorithm/iterator_operations.h+3
......@@ -219,6 +219,9 @@ private:
219219template <class _AlgPolicy, class _Iter>
220220using __policy_iter_diff_t _LIBCPP_NODEBUG = typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>;
221221
222template <class _AlgPolicy, class _Iter>
223using __policy_value_type _LIBCPP_NODEBUG = typename _IterOps<_AlgPolicy>::template __value_type<_Iter>;
224
222225_LIBCPP_END_NAMESPACE_STD
223226
224227_LIBCPP_POP_MACROS
lib/libcxx/include/__algorithm/lexicographical_compare.h+2-2
......@@ -66,8 +66,8 @@ template <class _Tp,
6666 class _Proj2,
6767 class _Comp,
6868 __enable_if_t<__desugars_to_v<__totally_ordered_less_tag, _Comp, _Tp, _Tp> && !is_volatile<_Tp>::value &&
69 __libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value &&
70 __is_identity<_Proj1>::value && __is_identity<_Proj2>::value,
69 __is_trivially_equality_comparable_v<_Tp, _Tp> && __is_identity<_Proj1>::value &&
70 __is_identity<_Proj2>::value,
7171 int> = 0>
7272_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
7373__lexicographical_compare(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Tp* __last2, _Comp&, _Proj1&, _Proj2&) {
lib/libcxx/include/__algorithm/lexicographical_compare_three_way.h+6-6
......@@ -37,13 +37,13 @@ template <class _InputIterator1, class _InputIterator2, class _Cmp>
3737_LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_fast_path(
3838 _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp)
3939 -> decltype(__comp(*__first1, *__first2)) {
40 static_assert(
41 signed_integral<__iter_diff_t<_InputIterator1>>, "Using a non-integral difference_type is undefined behavior.");
42 static_assert(
43 signed_integral<__iter_diff_t<_InputIterator2>>, "Using a non-integral difference_type is undefined behavior.");
40 static_assert(signed_integral<__iterator_difference_type<_InputIterator1>>,
41 "Using a non-integral difference_type is undefined behavior.");
42 static_assert(signed_integral<__iterator_difference_type<_InputIterator2>>,
43 "Using a non-integral difference_type is undefined behavior.");
4444
45 using _Len1 = __iter_diff_t<_InputIterator1>;
46 using _Len2 = __iter_diff_t<_InputIterator2>;
45 using _Len1 = __iterator_difference_type<_InputIterator1>;
46 using _Len2 = __iterator_difference_type<_InputIterator2>;
4747 using _Common = common_type_t<_Len1, _Len2>;
4848
4949 _Len1 __len1 = __last1 - __first1;
lib/libcxx/include/__algorithm/make_heap.h+16-4
......@@ -12,9 +12,11 @@
1212#include <__algorithm/comp.h>
1313#include <__algorithm/comp_ref_type.h>
1414#include <__algorithm/iterator_operations.h>
15#include <__algorithm/push_heap.h>
1516#include <__algorithm/sift_down.h>
1617#include <__config>
1718#include <__iterator/iterator_traits.h>
19#include <__type_traits/is_arithmetic.h>
1820#include <__utility/move.h>
1921
2022#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -31,13 +33,23 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
3133__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) {
3234 __comp_ref_type<_Compare> __comp_ref = __comp;
3335
34 using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
35 difference_type __n = __last - __first;
36 using __diff_t = __iterator_difference_type<_RandomAccessIterator>;
37 const __diff_t __n = __last - __first;
38
39 const bool __assume_both_children = is_arithmetic<__iterator_value_type<_RandomAccessIterator> >::value;
40
41 // While it would be correct to always assume we have both children, in practice we observed this to be a performance
42 // improvement only for arithmetic types.
43 const __diff_t __sift_down_n = __assume_both_children ? ((__n & 1) ? __n : __n - 1) : __n;
44
3645 if (__n > 1) {
3746 // start from the first parent, there is no need to consider children
38 for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) {
39 std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start);
47
48 for (__diff_t __start = (__sift_down_n - 2) / 2; __start >= 0; --__start) {
49 std::__sift_down<_AlgPolicy, __assume_both_children>(__first, __comp_ref, __sift_down_n, __start);
4050 }
51 if _LIBCPP_CONSTEXPR (__assume_both_children)
52 std::__sift_up<_AlgPolicy>(__first, __last, __comp, __n);
4153 }
4254}
4355
lib/libcxx/include/__algorithm/mismatch.h+2-2
......@@ -60,7 +60,7 @@ __mismatch(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Pred& __pred, _Pro
6060template <class _Iter>
6161[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter, _Iter>
6262__mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
63 using __value_type = __iter_value_type<_Iter>;
63 using __value_type = __iterator_value_type<_Iter>;
6464 constexpr size_t __unroll_count = 4;
6565 constexpr size_t __vec_size = __native_vector_size<__value_type>;
6666 using __vec = __simd_vector<__value_type, __vec_size>;
......@@ -136,7 +136,7 @@ template <class _Tp,
136136 class _Proj2,
137137 __enable_if_t<!is_integral<_Tp>::value && __desugars_to_v<__equal_tag, _Pred, _Tp, _Tp> &&
138138 __is_identity<_Proj1>::value && __is_identity<_Proj2>::value &&
139 __can_map_to_integer_v<_Tp> && __libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value,
139 __can_map_to_integer_v<_Tp> && __is_trivially_equality_comparable_v<_Tp, _Tp>,
140140 int> = 0>
141141[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*>
142142__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
lib/libcxx/include/__algorithm/move.h+8-19
......@@ -50,37 +50,26 @@ struct __move_impl {
5050 return std::make_pair(std::move(__first), std::move(__result));
5151 }
5252
53 template <class _InIter, class _OutIter>
54 struct _MoveSegment {
55 using _Traits _LIBCPP_NODEBUG = __segmented_iterator_traits<_InIter>;
56
57 _OutIter& __result_;
58
59 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit _MoveSegment(_OutIter& __result)
60 : __result_(__result) {}
61
62 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
63 operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
64 __result_ = std::__move<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second;
65 }
66 };
67
68 template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
53 template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
6954 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
7055 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
71 std::__for_each_segment(__first, __last, _MoveSegment<_InIter, _OutIter>(__result));
56 using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
57 std::__for_each_segment(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
58 __result = std::__move<_AlgPolicy>(__lfirst, __llast, std::move(__result)).second;
59 });
7260 return std::make_pair(__last, std::move(__result));
7361 }
7462
7563 template <class _InIter,
7664 class _OutIter,
7765 __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
78 !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
66 !__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>,
7967 int> = 0>
8068 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
8169 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
8270 using _Traits = __segmented_iterator_traits<_OutIter>;
83 using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
71 using _DiffT =
72 typename common_type<__iterator_difference_type<_InIter>, __iterator_difference_type<_OutIter> >::type;
8473
8574 if (__first == __last)
8675 return std::make_pair(std::move(__first), std::move(__result));
lib/libcxx/include/__algorithm/move_backward.h+9-24
......@@ -11,6 +11,7 @@
1111
1212#include <__algorithm/copy_backward.h>
1313#include <__algorithm/copy_move_common.h>
14#include <__algorithm/for_each_segment.h>
1415#include <__algorithm/iterator_operations.h>
1516#include <__algorithm/min.h>
1617#include <__config>
......@@ -51,42 +52,26 @@ struct __move_backward_impl {
5152 return std::make_pair(std::move(__original_last_iter), std::move(__result));
5253 }
5354
54 template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
55 template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
5556 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
5657 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
57 using _Traits = __segmented_iterator_traits<_InIter>;
58 auto __sfirst = _Traits::__segment(__first);
59 auto __slast = _Traits::__segment(__last);
60 if (__sfirst == __slast) {
61 auto __iters =
62 std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
63 return std::make_pair(__last, __iters.second);
64 }
65
66 __result =
67 std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
68 .second;
69 --__slast;
70 while (__sfirst != __slast) {
71 __result =
72 std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
73 .second;
74 --__slast;
75 }
76 __result = std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
77 .second;
58 using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
59 std::__for_each_segment_backward(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
60 __result = std::__move_backward<_AlgPolicy>(std::move(__lfirst), std::move(__llast), std::move(__result)).second;
61 });
7862 return std::make_pair(__last, std::move(__result));
7963 }
8064
8165 template <class _InIter,
8266 class _OutIter,
8367 __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
84 !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
68 !__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>,
8569 int> = 0>
8670 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
8771 operator()(_InIter __first, _InIter __last, _OutIter __result) const {
8872 using _Traits = __segmented_iterator_traits<_OutIter>;
89 using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
73 using _DiffT =
74 typename common_type<__iterator_difference_type<_InIter>, __iterator_difference_type<_OutIter> >::type;
9075
9176 // When the range contains no elements, __result might not be a valid iterator
9277 if (__first == __last)
lib/libcxx/include/__algorithm/none_of.h+4-4
......@@ -10,7 +10,9 @@
1010#ifndef _LIBCPP___ALGORITHM_NONE_OF_H
1111#define _LIBCPP___ALGORITHM_NONE_OF_H
1212
13#include <__algorithm/any_of.h>
1314#include <__config>
15#include <__functional/identity.h>
1416
1517#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1618# pragma GCC system_header
......@@ -21,10 +23,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2123template <class _InputIterator, class _Predicate>
2224[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
2325none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
24 for (; __first != __last; ++__first)
25 if (__pred(*__first))
26 return false;
27 return true;
26 __identity __proj;
27 return !std::__any_of(__first, __last, __pred, __proj);
2828}
2929
3030_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__algorithm/partial_sort.h+1-1
......@@ -45,7 +45,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator __part
4545 for (; __i != __last; ++__i) {
4646 if (__comp(*__i, *__first)) {
4747 _IterOps<_AlgPolicy>::iter_swap(__i, __first);
48 std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first);
48 std::__sift_down<_AlgPolicy, false>(__first, __comp, __len, 0);
4949 }
5050 }
5151 std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp);
lib/libcxx/include/__algorithm/partial_sort_copy.h+1-1
......@@ -60,7 +60,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _Random
6060 for (; __first != __last; ++__first)
6161 if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) {
6262 *__result_first = *__first;
63 std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first);
63 std::__sift_down<_AlgPolicy, false>(__result_first, __projected_comp, __len, 0);
6464 }
6565 std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
6666 }
lib/libcxx/include/__algorithm/pstl.h+9-9
......@@ -115,7 +115,7 @@ template <class _ExecutionPolicy,
115115 class _Predicate,
116116 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
117117 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
118_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
118[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __iterator_difference_type<_ForwardIterator>
119119count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
120120 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
121121 _ForwardIterator, "count_if(first, last, pred) requires [first, last) to be ForwardIterators");
......@@ -129,7 +129,7 @@ template <class _ExecutionPolicy,
129129 class _Tp,
130130 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
131131 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
132_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
132[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __iterator_difference_type<_ForwardIterator>
133133count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
134134 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
135135 _ForwardIterator, "count(first, last, val) requires [first, last) to be ForwardIterators");
......@@ -144,7 +144,7 @@ template <class _ExecutionPolicy,
144144 class _Pred,
145145 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
146146 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
147_LIBCPP_HIDE_FROM_ABI bool
147[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
148148equal(_ExecutionPolicy&& __policy,
149149 _ForwardIterator1 __first1,
150150 _ForwardIterator1 __last1,
......@@ -166,7 +166,7 @@ template <class _ExecutionPolicy,
166166 class _ForwardIterator2,
167167 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
168168 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
169_LIBCPP_HIDE_FROM_ABI bool
169[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
170170equal(_ExecutionPolicy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
171171 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
172172 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
......@@ -185,7 +185,7 @@ template <class _ExecutionPolicy,
185185 class _Pred,
186186 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
187187 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
188_LIBCPP_HIDE_FROM_ABI bool
188[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
189189equal(_ExecutionPolicy&& __policy,
190190 _ForwardIterator1 __first1,
191191 _ForwardIterator1 __last1,
......@@ -209,7 +209,7 @@ template <class _ExecutionPolicy,
209209 class _ForwardIterator2,
210210 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
211211 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
212_LIBCPP_HIDE_FROM_ABI bool
212[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
213213equal(_ExecutionPolicy&& __policy,
214214 _ForwardIterator1 __first1,
215215 _ForwardIterator1 __last1,
......@@ -259,7 +259,7 @@ template <class _ExecutionPolicy,
259259 class _Predicate,
260260 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
261261 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
262_LIBCPP_HIDE_FROM_ABI _ForwardIterator
262[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _ForwardIterator
263263find_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
264264 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if requires ForwardIterators");
265265 using _Implementation = __pstl::__dispatch<__pstl::__find_if, __pstl::__current_configuration, _RawPolicy>;
......@@ -272,7 +272,7 @@ template <class _ExecutionPolicy,
272272 class _Predicate,
273273 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
274274 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
275_LIBCPP_HIDE_FROM_ABI _ForwardIterator
275[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _ForwardIterator
276276find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
277277 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if_not requires ForwardIterators");
278278 using _Implementation = __pstl::__dispatch<__pstl::__find_if_not, __pstl::__current_configuration, _RawPolicy>;
......@@ -285,7 +285,7 @@ template <class _ExecutionPolicy,
285285 class _Tp,
286286 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
287287 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
288_LIBCPP_HIDE_FROM_ABI _ForwardIterator
288[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _ForwardIterator
289289find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
290290 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find requires ForwardIterators");
291291 using _Implementation = __pstl::__dispatch<__pstl::__find, __pstl::__current_configuration, _RawPolicy>;
lib/libcxx/include/__algorithm/radix_sort.h+27-25
......@@ -72,14 +72,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD
7272#if _LIBCPP_STD_VER >= 14
7373
7474template <class _InputIterator, class _OutputIterator>
75_LIBCPP_HIDE_FROM_ABI constexpr pair<_OutputIterator, __iter_value_type<_InputIterator>>
75_LIBCPP_HIDE_FROM_ABI constexpr pair<_OutputIterator, __iterator_value_type<_InputIterator>>
7676__partial_sum_max(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
7777 if (__first == __last)
7878 return {__result, 0};
7979
80 auto __max = *__first;
81 __iter_value_type<_InputIterator> __sum = *__first;
82 *__result = __sum;
80 auto __max = *__first;
81 __iterator_value_type<_InputIterator> __sum = *__first;
82 *__result = __sum;
8383
8484 while (++__first != __last) {
8585 if (__max < *__first) {
......@@ -124,7 +124,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __nth_radix(size_t __radix_number, _Radix _
124124template <class _ForwardIterator, class _Map, class _RandomAccessIterator>
125125_LIBCPP_HIDE_FROM_ABI constexpr void
126126__collect(_ForwardIterator __first, _ForwardIterator __last, _Map __map, _RandomAccessIterator __counters) {
127 using __value_type = __iter_value_type<_ForwardIterator>;
127 using __value_type = __iterator_value_type<_ForwardIterator>;
128128 using __traits = __counting_sort_traits<__value_type, _Map>;
129129
130130 std::for_each(__first, __last, [&__counters, &__map](const auto& __preimage) { ++__counters[__map(__preimage)]; });
......@@ -160,7 +160,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __collect_impl(
160160 _RandomAccessIterator1 __counters,
161161 _RandomAccessIterator2 __maximums,
162162 index_sequence<_Radices...>) {
163 using __value_type = __iter_value_type<_ForwardIterator>;
163 using __value_type = __iterator_value_type<_ForwardIterator>;
164164 constexpr auto __radix_value_range = __radix_sort_traits<__value_type, _Map, _Radix>::__radix_value_range;
165165
166166 auto __previous = numeric_limits<__invoke_result_t<_Map, __value_type>>::min();
......@@ -189,7 +189,7 @@ __collect(_ForwardIterator __first,
189189 _Radix __radix,
190190 _RandomAccessIterator1 __counters,
191191 _RandomAccessIterator2 __maximums) {
192 using __value_type = __iter_value_type<_ForwardIterator>;
192 using __value_type = __iterator_value_type<_ForwardIterator>;
193193 constexpr auto __radix_count = __radix_sort_traits<__value_type, _Map, _Radix>::__radix_count;
194194 return std::__collect_impl(
195195 __first, __last, __map, __radix, __counters, __maximums, make_index_sequence<__radix_count>());
......@@ -213,10 +213,10 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __dispose_backward(
213213template <class _ForwardIterator, class _RandomAccessIterator, class _Map>
214214_LIBCPP_HIDE_FROM_ABI constexpr _RandomAccessIterator
215215__counting_sort_impl(_ForwardIterator __first, _ForwardIterator __last, _RandomAccessIterator __result, _Map __map) {
216 using __value_type = __iter_value_type<_ForwardIterator>;
216 using __value_type = __iterator_value_type<_ForwardIterator>;
217217 using __traits = __counting_sort_traits<__value_type, _Map>;
218218
219 __iter_diff_t<_RandomAccessIterator> __counters[__traits::__value_range + 1] = {0};
219 __iterator_difference_type<_RandomAccessIterator> __counters[__traits::__value_range + 1] = {0};
220220
221221 std::__collect(__first, __last, __map, std::next(std::begin(__counters)));
222222 std::__dispose(__first, __last, __result, __map, std::begin(__counters));
......@@ -224,12 +224,13 @@ __counting_sort_impl(_ForwardIterator __first, _ForwardIterator __last, _RandomA
224224 return __result + __counters[__traits::__value_range];
225225}
226226
227template <class _RandomAccessIterator1,
228 class _RandomAccessIterator2,
229 class _Map,
230 class _Radix,
231 enable_if_t< __radix_sort_traits<__iter_value_type<_RandomAccessIterator1>, _Map, _Radix>::__radix_count == 1,
232 int> = 0>
227template <
228 class _RandomAccessIterator1,
229 class _RandomAccessIterator2,
230 class _Map,
231 class _Radix,
232 enable_if_t<__radix_sort_traits<__iterator_value_type<_RandomAccessIterator1>, _Map, _Radix>::__radix_count == 1,
233 int> = 0>
233234_LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort_impl(
234235 _RandomAccessIterator1 __first,
235236 _RandomAccessIterator1 __last,
......@@ -243,24 +244,25 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort_impl(
243244 std::move(__buffer, __buffer_end, __first);
244245}
245246
246template <
247 class _RandomAccessIterator1,
248 class _RandomAccessIterator2,
249 class _Map,
250 class _Radix,
251 enable_if_t< __radix_sort_traits<__iter_value_type<_RandomAccessIterator1>, _Map, _Radix>::__radix_count % 2 == 0,
252 int> = 0 >
247template <class _RandomAccessIterator1,
248 class _RandomAccessIterator2,
249 class _Map,
250 class _Radix,
251 enable_if_t<
252 __radix_sort_traits<__iterator_value_type<_RandomAccessIterator1>, _Map, _Radix>::__radix_count % 2 == 0,
253 int> = 0>
253254_LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort_impl(
254255 _RandomAccessIterator1 __first,
255256 _RandomAccessIterator1 __last,
256257 _RandomAccessIterator2 __buffer_begin,
257258 _Map __map,
258259 _Radix __radix) {
259 using __value_type = __iter_value_type<_RandomAccessIterator1>;
260 using __value_type = __iterator_value_type<_RandomAccessIterator1>;
260261 using __traits = __radix_sort_traits<__value_type, _Map, _Radix>;
261262
262 __iter_diff_t<_RandomAccessIterator1> __counters[__traits::__radix_count][__traits::__radix_value_range] = {{0}};
263 __iter_diff_t<_RandomAccessIterator1> __maximums[__traits::__radix_count] = {0};
263 __iterator_difference_type<_RandomAccessIterator1>
264 __counters[__traits::__radix_count][__traits::__radix_value_range] = {{0}};
265 __iterator_difference_type<_RandomAccessIterator1> __maximums[__traits::__radix_count] = {0};
264266 const auto __is_sorted = std::__collect(__first, __last, __map, __radix, __counters, __maximums);
265267 if (!__is_sorted) {
266268 const auto __range_size = std::distance(__first, __last);
lib/libcxx/include/__algorithm/ranges_copy_n.h+3-26
......@@ -9,16 +9,12 @@
99#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_N_H
1010#define _LIBCPP___ALGORITHM_RANGES_COPY_N_H
1111
12#include <__algorithm/copy.h>
12#include <__algorithm/copy_n.h>
1313#include <__algorithm/in_out_result.h>
1414#include <__algorithm/iterator_operations.h>
15#include <__algorithm/ranges_copy.h>
1615#include <__config>
17#include <__functional/identity.h>
1816#include <__iterator/concepts.h>
1917#include <__iterator/incrementable_traits.h>
20#include <__iterator/unreachable_sentinel.h>
21#include <__iterator/wrap_iter.h>
2218#include <__utility/move.h>
2319
2420#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -37,32 +33,13 @@ namespace ranges {
3733template <class _Ip, class _Op>
3834using copy_n_result = in_out_result<_Ip, _Op>;
3935
40// TODO: Merge this with copy_n
4136struct __copy_n {
42 template <class _InIter, class _DiffType, class _OutIter>
43 _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
44 __go(_InIter __first, _DiffType __n, _OutIter __result) {
45 while (__n != 0) {
46 *__result = *__first;
47 ++__first;
48 ++__result;
49 --__n;
50 }
51 return {std::move(__first), std::move(__result)};
52 }
53
54 template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter>
55 _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
56 __go(_InIter __first, _DiffType __n, _OutIter __result) {
57 auto __ret = std::__copy(__first, __first + __n, __result);
58 return {__ret.first, __ret.second};
59 }
60
6137 template <input_iterator _Ip, weakly_incrementable _Op>
6238 requires indirectly_copyable<_Ip, _Op>
6339 _LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op>
6440 operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
65 return __go(std::move(__first), __n, std::move(__result));
41 auto __res = std::__copy_n<_RangeAlgPolicy>(std::move(__first), __n, std::move(__result));
42 return {std::move(__res.first), std::move(__res.second)};
6643 }
6744};
6845
lib/libcxx/include/__algorithm/ranges_equal.h+17-26
......@@ -13,13 +13,12 @@
1313#include <__algorithm/unwrap_range.h>
1414#include <__config>
1515#include <__functional/identity.h>
16#include <__functional/invoke.h>
1716#include <__functional/ranges_operations.h>
1817#include <__iterator/concepts.h>
19#include <__iterator/distance.h>
2018#include <__iterator/indirectly_comparable.h>
2119#include <__ranges/access.h>
2220#include <__ranges/concepts.h>
21#include <__ranges/size.h>
2322#include <__utility/move.h>
2423
2524#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -51,20 +50,17 @@ struct __equal {
5150 _Pred __pred = {},
5251 _Proj1 __proj1 = {},
5352 _Proj2 __proj2 = {}) const {
54 if constexpr (sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>) {
53 static constexpr bool __both_sized = sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>;
54 if constexpr (__both_sized) {
5555 if (__last1 - __first1 != __last2 - __first2)
5656 return false;
5757 }
58 auto __unwrapped1 = std::__unwrap_range(std::move(__first1), std::move(__last1));
59 auto __unwrapped2 = std::__unwrap_range(std::move(__first2), std::move(__last2));
60 return std::__equal_impl(
61 std::move(__unwrapped1.first),
62 std::move(__unwrapped1.second),
63 std::move(__unwrapped2.first),
64 std::move(__unwrapped2.second),
65 __pred,
66 __proj1,
67 __proj2);
58
59 auto [__ufirst1, __ulast1] = std::__unwrap_range(std::move(__first1), std::move(__last1));
60 auto [__ufirst2, __ulast2] = std::__unwrap_range(std::move(__first2), std::move(__last2));
61
62 return std::__equal_impl<__both_sized>(
63 std::move(__ufirst1), std::move(__ulast1), std::move(__ufirst2), std::move(__ulast2), __pred, __proj1, __proj2);
6864 }
6965
7066 template <input_range _Range1,
......@@ -75,21 +71,16 @@ struct __equal {
7571 requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
7672 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
7773 _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
78 if constexpr (sized_range<_Range1> && sized_range<_Range2>) {
79 if (ranges::distance(__range1) != ranges::distance(__range2))
74 static constexpr bool __both_sized = sized_range<_Range1> && sized_range<_Range2>;
75 if constexpr (__both_sized) {
76 if (ranges::size(__range1) != ranges::size(__range2))
8077 return false;
8178 }
82 auto __unwrapped1 = std::__unwrap_range(ranges::begin(__range1), ranges::end(__range1));
83 auto __unwrapped2 = std::__unwrap_range(ranges::begin(__range2), ranges::end(__range2));
84 return std::__equal_impl(
85 std::move(__unwrapped1.first),
86 std::move(__unwrapped1.second),
87 std::move(__unwrapped2.first),
88 std::move(__unwrapped2.second),
89 __pred,
90 __proj1,
91 __proj2);
92 return false;
79
80 auto [__ufirst1, __ulast1] = std::__unwrap_range(ranges::begin(__range1), ranges::end(__range1));
81 auto [__ufirst2, __ulast2] = std::__unwrap_range(ranges::begin(__range2), ranges::end(__range2));
82 return std::__equal_impl<__both_sized>(
83 std::move(__ufirst1), std::move(__ulast1), std::move(__ufirst2), std::move(__ulast2), __pred, __proj1, __proj2);
9384 }
9485};
9586
lib/libcxx/include/__algorithm/ranges_fill.h+7-6
......@@ -9,12 +9,14 @@
99#ifndef _LIBCPP___ALGORITHM_RANGES_FILL_H
1010#define _LIBCPP___ALGORITHM_RANGES_FILL_H
1111
12#include <__algorithm/ranges_fill_n.h>
12#include <__algorithm/fill.h>
13#include <__algorithm/fill_n.h>
1314#include <__config>
1415#include <__iterator/concepts.h>
1516#include <__ranges/access.h>
1617#include <__ranges/concepts.h>
1718#include <__ranges/dangling.h>
19#include <__utility/move.h>
1820
1921#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2022# pragma GCC system_header
......@@ -31,12 +33,11 @@ namespace ranges {
3133struct __fill {
3234 template <class _Type, output_iterator<const _Type&> _Iter, sentinel_for<_Iter> _Sent>
3335 _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const {
34 if constexpr (random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) {
35 return ranges::fill_n(__first, __last - __first, __value);
36 if constexpr (sized_sentinel_for<_Sent, _Iter>) {
37 auto __n = __last - __first;
38 return std::__fill_n(std::move(__first), __n, __value);
3639 } else {
37 for (; __first != __last; ++__first)
38 *__first = __value;
39 return __first;
40 return std::__fill(std::move(__first), std::move(__last), __value);
4041 }
4142 }
4243
lib/libcxx/include/__algorithm/ranges_for_each.h+9-1
......@@ -12,6 +12,7 @@
1212#include <__algorithm/for_each.h>
1313#include <__algorithm/for_each_n.h>
1414#include <__algorithm/in_fun_result.h>
15#include <__algorithm/specialized_algorithms.h>
1516#include <__concepts/assignable.h>
1617#include <__config>
1718#include <__functional/identity.h>
......@@ -20,6 +21,7 @@
2021#include <__ranges/access.h>
2122#include <__ranges/concepts.h>
2223#include <__ranges/dangling.h>
24#include <__type_traits/remove_cvref.h>
2325#include <__utility/move.h>
2426
2527#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -71,7 +73,13 @@ public:
7173 indirectly_unary_invocable<projected<iterator_t<_Range>, _Proj>> _Func>
7274 _LIBCPP_HIDE_FROM_ABI constexpr for_each_result<borrowed_iterator_t<_Range>, _Func>
7375 operator()(_Range&& __range, _Func __func, _Proj __proj = {}) const {
74 return __for_each_impl(ranges::begin(__range), ranges::end(__range), __func, __proj);
76 using _SpecialAlg = __specialized_algorithm<_Algorithm::__for_each, __single_range<remove_cvref_t<_Range>>>;
77 if constexpr (_SpecialAlg::__has_algorithm) {
78 auto [__iter, __func2] = _SpecialAlg()(__range, std::move(__func), std::move(__proj));
79 return {std::move(__iter), std::move(__func)};
80 } else {
81 return __for_each_impl(ranges::begin(__range), ranges::end(__range), __func, __proj);
82 }
7583 }
7684};
7785
lib/libcxx/include/__algorithm/ranges_generate_n.h+2-6
......@@ -9,6 +9,7 @@
99#ifndef _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H
1010#define _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H
1111
12#include <__algorithm/generate_n.h>
1213#include <__concepts/constructible.h>
1314#include <__concepts/invocable.h>
1415#include <__config>
......@@ -38,12 +39,7 @@ struct __generate_n {
3839 requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>>
3940 _LIBCPP_HIDE_FROM_ABI constexpr _OutIter
4041 operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const {
41 for (; __n > 0; --__n) {
42 *__first = __gen();
43 ++__first;
44 }
45
46 return __first;
42 return std::__generate_n(std::move(__first), __n, __gen);
4743 }
4844};
4945
lib/libcxx/include/__algorithm/ranges_search_n.h+2-2
......@@ -54,8 +54,8 @@ struct __search_n {
5454 }
5555
5656 if constexpr (random_access_iterator<_Iter1>) {
57 auto __ret = std::__search_n_random_access_impl<_RangeAlgPolicy>(
58 __first, __last, __count, __value, __pred, __proj, __size);
57 auto __ret =
58 std::__search_n_random_access_impl<_RangeAlgPolicy>(__first, __count, __value, __pred, __proj, __size);
5959 return {std::move(__ret.first), std::move(__ret.second)};
6060 }
6161 }
lib/libcxx/include/__algorithm/rotate.h+27-44
......@@ -12,16 +12,13 @@
1212#include <__algorithm/copy.h>
1313#include <__algorithm/copy_backward.h>
1414#include <__algorithm/iterator_operations.h>
15#include <__algorithm/min.h>
1516#include <__algorithm/move.h>
1617#include <__algorithm/move_backward.h>
1718#include <__algorithm/swap_ranges.h>
1819#include <__config>
19#include <__cstddef/size_t.h>
2020#include <__fwd/bit_reference.h>
2121#include <__iterator/iterator_traits.h>
22#include <__memory/construct_at.h>
23#include <__memory/pointer_traits.h>
24#include <__type_traits/is_constant_evaluated.h>
2522#include <__type_traits/is_trivially_assignable.h>
2623#include <__utility/move.h>
2724#include <__utility/pair.h>
......@@ -89,46 +86,32 @@ __rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIt
8986 return __r;
9087}
9188
92template <typename _Integral>
93inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral __algo_gcd(_Integral __x, _Integral __y) {
94 do {
95 _Integral __t = __x % __y;
96 __x = __y;
97 __y = __t;
98 } while (__y);
99 return __x;
100}
101
102template <class _AlgPolicy, typename _RandomAccessIterator>
103_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _RandomAccessIterator
104__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) {
105 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
106 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
107 using _Ops = _IterOps<_AlgPolicy>;
108
109 const difference_type __m1 = __middle - __first;
110 const difference_type __m2 = _Ops::distance(__middle, __last);
111 if (__m1 == __m2) {
112 std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last);
113 return __middle;
114 }
115 const difference_type __g = std::__algo_gcd(__m1, __m2);
116 for (_RandomAccessIterator __p = __first + __g; __p != __first;) {
117 value_type __t(_Ops::__iter_move(--__p));
118 _RandomAccessIterator __p1 = __p;
119 _RandomAccessIterator __p2 = __p1 + __m1;
120 do {
121 *__p1 = _Ops::__iter_move(__p2);
122 __p1 = __p2;
123 const difference_type __d = _Ops::distance(__p2, __last);
124 if (__m1 < __d)
125 __p2 += __m1;
126 else
127 __p2 = __first + (__m1 - __d);
128 } while (__p2 != __p);
129 *__p1 = std::move(__t);
89template <class _AlgPolicy, class _Iter, class _Sent>
90_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Iter
91__rotate_random_access(_Iter __first, _Iter __middle, _Sent __sent) {
92 auto __left = _IterOps<_AlgPolicy>::distance(__first, __middle);
93 auto __right = _IterOps<_AlgPolicy>::distance(__middle, __sent);
94 auto __last = __first + __right;
95
96 auto __min_len = std::min(__left, __right);
97
98 while (__min_len > 0) {
99 if (__left <= __right) {
100 do {
101 std::__swap_ranges<_AlgPolicy>(__first, __first + __left, __first + __left);
102 __first += __left;
103 __right -= __left;
104 } while (__left <= __right);
105 __min_len = __right;
106 } else {
107 do {
108 std::__swap_ranges<_AlgPolicy>(__first + (__left - __right), __first + __left, __first + __left);
109 __left -= __right;
110 } while (__left > __right);
111 __min_len = __left;
112 }
130113 }
131 return __first + __m2;
114 return __last;
132115}
133116
134117template <class _AlgPolicy, class _ForwardIterator>
......@@ -170,7 +153,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator
170153 return std::__rotate_left<_AlgPolicy>(__first, __last);
171154 if (_IterOps<_AlgPolicy>::next(__middle) == __last)
172155 return std::__rotate_right<_AlgPolicy>(__first, __last);
173 return std::__rotate_gcd<_AlgPolicy>(__first, __middle, __last);
156 return std::__rotate_random_access<_AlgPolicy>(__first, __middle, __last);
174157 }
175158 return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
176159}
lib/libcxx/include/__algorithm/search_n.h+49-37
......@@ -14,11 +14,7 @@
1414#include <__algorithm/iterator_operations.h>
1515#include <__config>
1616#include <__functional/identity.h>
17#include <__iterator/advance.h>
18#include <__iterator/concepts.h>
19#include <__iterator/distance.h>
2017#include <__iterator/iterator_traits.h>
21#include <__ranges/concepts.h>
2218#include <__type_traits/enable_if.h>
2319#include <__type_traits/invoke.h>
2420#include <__type_traits/is_callable.h>
......@@ -68,44 +64,60 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> __search_
6864 }
6965}
7066
71template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj, class _DiffT>
67// Finds the longest suffix in [__first, __last) where each element satisfies __pred.
68template <class _RAIter, class _Pred, class _Proj, class _ValueT>
69_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RAIter
70__find_longest_suffix(_RAIter __first, _RAIter __last, const _ValueT& __value, _Pred& __pred, _Proj& __proj) {
71 while (__first != __last) {
72 if (!std::__invoke(__pred, std::__invoke(__proj, *--__last), __value)) {
73 return ++__last;
74 }
75 }
76 return __first;
77}
78
79template <class _AlgPolicy, class _Pred, class _Iter, class _SizeT, class _Type, class _Proj, class _DiffT>
7280_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 std::pair<_Iter, _Iter> __search_n_random_access_impl(
73 _Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj, _DiffT __size1) {
74 using difference_type = typename iterator_traits<_Iter>::difference_type;
81 _Iter __first, _SizeT __count_in, const _Type& __value, _Pred& __pred, _Proj& __proj, _DiffT __size) {
82 auto __last = __first + __size;
83 auto __count = static_cast<_DiffT>(__count_in);
84
7585 if (__count == 0)
7686 return std::make_pair(__first, __first);
77 if (__size1 < static_cast<_DiffT>(__count)) {
78 _IterOps<_AlgPolicy>::__advance_to(__first, __last);
79 return std::make_pair(__first, __first);
80 }
87 if (__size < __count)
88 return std::make_pair(__last, __last);
89
90 // [__match_start, __match_start + __count) is the subrange which we currently check whether it only contains matching
91 // elements. This subrange is returned in case all the elements match.
92 // [__match_start, __matched_until) is the longest subrange where all elements are known to match at any given point
93 // in time.
94 // [__matched_until, __match_start + __count) is the subrange where we don't know whether the elements match.
95
96 // This algorithm tries to expand the subrange [__match_start, __matched_until) into a range of sufficient length.
97 // When we fail to do that because we find a mismatching element, we move it forward to the beginning of the next
98 // consecutive sequence that is not known not to match.
99
100 const _Iter __try_match_until = __last - __count;
101 _Iter __match_start = __first;
102 _Iter __matched_until = __first;
81103
82 const auto __s = __first + __size1 - difference_type(__count - 1); // Start of pattern match can't go beyond here
83104 while (true) {
84 // Find first element in sequence that matchs __value, with a mininum of loop checks
85 while (true) {
86 if (__first >= __s) { // return __last if no element matches __value
87 _IterOps<_AlgPolicy>::__advance_to(__first, __last);
88 return std::make_pair(__first, __first);
89 }
90 if (std::__invoke(__pred, std::__invoke(__proj, *__first), __value))
91 break;
92 ++__first;
93 }
94 // *__first matches __value_, now match elements after here
95 auto __m = __first;
96 _SizeT __c(0);
97 while (true) {
98 if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern)
99 return std::make_pair(__first, __first + _DiffT(__count));
100 ++__m; // no need to check range on __m because __s guarantees we have enough source
105 // There's no chance of expanding the subrange into a sequence of sufficient length, since we don't have enough
106 // elements in the haystack anymore.
107 if (__match_start > __try_match_until)
108 return std::make_pair(__last, __last);
101109
102 // if there is a mismatch, restart with a new __first
103 if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) {
104 __first = __m;
105 ++__first;
106 break;
107 } // else there is a match, check next elements
108 }
110 auto __mismatch = std::__find_longest_suffix(__matched_until, __match_start + __count, __value, __pred, __proj);
111
112 // If all elements in [__matched_until, __match_start + __count) match, we know that
113 // [__match_start, __match_start + __count) is a full sequence of matching elements, so we're done.
114 if (__mismatch == __matched_until)
115 return std::make_pair(__match_start, __match_start + __count);
116
117 // Otherwise, we have to move the [__match_start, __matched_until) subrange forward past the point where we know for
118 // sure a match is impossible.
119 __matched_until = __match_start + __count;
120 __match_start = __mismatch;
109121 }
110122}
111123
......@@ -119,7 +131,7 @@ template <class _Iter,
119131_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter>
120132__search_n_impl(_Iter __first, _Sent __last, _DiffT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) {
121133 return std::__search_n_random_access_impl<_ClassicAlgPolicy>(
122 __first, __last, __count, __value, __pred, __proj, __last - __first);
134 __first, __count, __value, __pred, __proj, __last - __first);
123135}
124136
125137template <class _Iter1,
lib/libcxx/include/__algorithm/sift_down.h+19-18
......@@ -24,59 +24,60 @@ _LIBCPP_PUSH_MACROS
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
27template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
27template <class _AlgPolicy, bool __assume_both_children, class _Compare, class _RandomAccessIterator>
2828_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
2929__sift_down(_RandomAccessIterator __first,
3030 _Compare&& __comp,
31 typename iterator_traits<_RandomAccessIterator>::difference_type __len,
32 _RandomAccessIterator __start) {
31 __iterator_difference_type<_RandomAccessIterator> __len,
32 __iterator_difference_type<_RandomAccessIterator> __start) {
3333 using _Ops = _IterOps<_AlgPolicy>;
3434
3535 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
3636 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
3737 // left-child of __start is at 2 * __start + 1
3838 // right-child of __start is at 2 * __start + 2
39 difference_type __child = __start - __first;
39 difference_type __child = __start;
4040
4141 if (__len < 2 || (__len - 2) / 2 < __child)
4242 return;
4343
44 __child = 2 * __child + 1;
45 _RandomAccessIterator __child_i = __first + __child;
44 __child = 2 * __child + 1;
4645
47 if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
46 if _LIBCPP_CONSTEXPR (__assume_both_children) {
47 // right-child exists and is greater than left-child
48 __child += __comp(__first[__child], __first[__child + 1]);
49 } else if ((__child + 1) < __len && __comp(__first[__child], __first[__child + 1])) {
4850 // right-child exists and is greater than left-child
49 ++__child_i;
5051 ++__child;
5152 }
5253
5354 // check if we are in heap-order
54 if (__comp(*__child_i, *__start))
55 if (__comp(__first[__child], __first[__start]))
5556 // we are, __start is larger than its largest child
5657 return;
5758
58 value_type __top(_Ops::__iter_move(__start));
59 value_type __top(_Ops::__iter_move(__first + __start));
5960 do {
6061 // we are not in heap-order, swap the parent with its largest child
61 *__start = _Ops::__iter_move(__child_i);
62 __start = __child_i;
62 __first[__start] = _Ops::__iter_move(__first + __child);
63 __start = __child;
6364
6465 if ((__len - 2) / 2 < __child)
6566 break;
6667
6768 // recompute the child based off of the updated parent
68 __child = 2 * __child + 1;
69 __child_i = __first + __child;
69 __child = 2 * __child + 1;
7070
71 if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
71 if _LIBCPP_CONSTEXPR (__assume_both_children) {
72 __child += __comp(__first[__child], __first[__child + 1]);
73 } else if ((__child + 1) < __len && __comp(__first[__child], __first[__child + 1])) {
7274 // right-child exists and is greater than left-child
73 ++__child_i;
7475 ++__child;
7576 }
7677
7778 // check if we are in heap-order
78 } while (!__comp(*__child_i, __top));
79 *__start = std::move(__top);
79 } while (!__comp(__first[__child], __top));
80 __first[__start] = std::move(__top);
8081}
8182
8283template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
lib/libcxx/include/__algorithm/simd_utils.h+33-4
......@@ -26,9 +26,7 @@ _LIBCPP_PUSH_MACROS
2626#include <__undef_macros>
2727
2828// TODO: Find out how altivec changes things and allow vectorizations there too.
29// TODO: Simplify this condition once we stop building with AppleClang 15 in the CI.
30#if _LIBCPP_STD_VER >= 14 && defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(__ALTIVEC__) && \
31 !(defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600)
29#if _LIBCPP_STD_VER >= 14 && defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(__ALTIVEC__)
3230# define _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS 1
3331#else
3432# define _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS 0
......@@ -116,16 +114,47 @@ template <class _VecT, class _Iter>
116114 }(make_index_sequence<__simd_vector_size_v<_VecT>>{});
117115}
118116
117// Load the first _Np elements, zero the rest
118_LIBCPP_DIAGNOSTIC_PUSH
119_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpsabi")
120template <class _VecT, size_t _Np, class _Iter>
121[[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _VecT __partial_load(_Iter __iter) noexcept {
122 return [=]<size_t... _LoadIndices, size_t... _ZeroIndices>(
123 index_sequence<_LoadIndices...>, index_sequence<_ZeroIndices...>) _LIBCPP_ALWAYS_INLINE noexcept {
124 return _VecT{__iter[_LoadIndices]..., ((void)_ZeroIndices, 0)...};
125 }(make_index_sequence<_Np>{}, make_index_sequence<__simd_vector_size_v<_VecT> - _Np>{});
126}
127
128// Create a vector where every elements is __val
129template <class _VecT>
130[[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _VecT
131__broadcast(__simd_vector_underlying_type_t<_VecT> __val) {
132 return [&]<std::size_t... _Indices>(index_sequence<_Indices...>) {
133 return _VecT{((void)_Indices, __val)...};
134 }(make_index_sequence<__simd_vector_size_v<_VecT>>());
135}
136_LIBCPP_DIAGNOSTIC_POP
137
138template <class _Tp, size_t _Np>
139[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __any_of(__simd_vector<_Tp, _Np> __vec) noexcept {
140 return __builtin_reduce_or(__builtin_convertvector(__vec, __simd_vector<bool, _Np>));
141}
142
119143template <class _Tp, size_t _Np>
120144[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __all_of(__simd_vector<_Tp, _Np> __vec) noexcept {
121145 return __builtin_reduce_and(__builtin_convertvector(__vec, __simd_vector<bool, _Np>));
122146}
123147
148template <class _Tp, size_t _Np>
149[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __none_of(__simd_vector<_Tp, _Np> __vec) noexcept {
150 return !__builtin_reduce_or(__builtin_convertvector(__vec, __simd_vector<bool, _Np>));
151}
152
124153template <class _Tp, size_t _Np>
125154[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t __find_first_set(__simd_vector<_Tp, _Np> __vec) noexcept {
126155 using __mask_vec = __simd_vector<bool, _Np>;
127156
128 // This has MSan disabled du to https://github.com/llvm/llvm-project/issues/85876
157 // This has MSan disabled du to https://llvm.org/PR85876
129158 auto __impl = [&]<class _MaskT>(_MaskT) _LIBCPP_NO_SANITIZE("memory") noexcept {
130159# if defined(_LIBCPP_BIG_ENDIAN)
131160 return std::min<size_t>(
lib/libcxx/include/__algorithm/specialized_algorithms.h created+54
......@@ -0,0 +1,54 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_SPECIALIZED_ALGORITHMS_H
10#define _LIBCPP___ALGORITHM_SPECIALIZED_ALGORITHMS_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15# pragma GCC system_header
16#endif
17
18_LIBCPP_BEGIN_NAMESPACE_STD
19
20namespace _Algorithm {
21struct __copy {};
22struct __fill_n {};
23struct __for_each {};
24} // namespace _Algorithm
25
26template <class>
27struct __single_iterator;
28
29template <class, class>
30struct __iterator_pair;
31
32template <class>
33struct __single_range;
34
35// This struct allows specializing algorithms for specific arguments. This is useful when we know a more efficient
36// algorithm implementation for e.g. library-defined iterators. _Alg is one of tags defined inside the _Algorithm
37// namespace above. _Ranges is an essentially arbitrary subset of the arguments to the algorithm that are used for
38// dispatching. This set is specific to the algorithm: look at each algorithm to see which arguments they use for
39// dispatching to specialized algorithms.
40//
41// A specialization of `__specialized_algorithm` has to define `__has_algorithm` to true for the specialized algorithm
42// to be used. This is intended for cases where iterators can do generic unwrapping and forward to a different
43// specialization of `__specialized_algorithm`.
44//
45// If __has_algorithm is true, there has to be an operator() which will get called with the actual arguments to the
46// algorithm.
47template <class _Alg, class... _Ranges>
48struct __specialized_algorithm {
49 static const bool __has_algorithm = false;
50};
51
52_LIBCPP_END_NAMESPACE_STD
53
54#endif // _LIBCPP___ALGORITHM_SPECIALIZED_ALGORITHMS_H
lib/libcxx/include/__algorithm/stable_sort.h+1-1
......@@ -247,7 +247,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void __stable_sort(
247247 constexpr auto __default_comp = __desugars_to_v<__less_tag, _Compare, value_type, value_type >;
248248 constexpr auto __radix_sortable =
249249 __is_ordered_integer_representable_v<value_type> &&
250 is_same_v< value_type&, __iter_reference<_RandomAccessIterator>>;
250 is_same_v< value_type&, __iterator_reference<_RandomAccessIterator>>;
251251 if constexpr (__default_comp && __radix_sortable) {
252252 if (__len <= __buff_size && __len >= static_cast<difference_type>(std::__radix_sort_min_bound<value_type>()) &&
253253 __len <= static_cast<difference_type>(std::__radix_sort_max_bound<value_type>())) {
lib/libcxx/include/__assertion_handler+31-4
......@@ -16,6 +16,7 @@
1616# include <__cxx03/__verbose_trap>
1717#else
1818# include <__config>
19# include <__log_hardening_failure>
1920# include <__verbose_abort>
2021# include <__verbose_trap>
2122#endif
......@@ -24,14 +25,40 @@
2425# pragma GCC system_header
2526#endif
2627
27#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
28#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
2829
29# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_ABORT("%s", message)
30// Keep the old implementation that doesn't support assertion semantics for backward compatibility with the frozen C++03
31// mode.
32# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
33# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_ABORT("%s", message)
34# else
35# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message)
36# endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
3037
3138#else
3239
33# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message)
40# if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_IGNORE
41# define _LIBCPP_ASSERTION_HANDLER(message) ((void)0)
42
43# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE
44# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_LOG_HARDENING_FAILURE(message)
45
46# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
47# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message)
48
49# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
50# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_ABORT("%s", message)
51
52# else
53
54# error _LIBCPP_ASSERTION_SEMANTIC must be set to one of the following values: \
55_LIBCPP_ASSERTION_SEMANTIC_IGNORE, \
56_LIBCPP_ASSERTION_SEMANTIC_OBSERVE, \
57_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE, \
58_LIBCPP_ASSERTION_SEMANTIC_ENFORCE
59
60# endif // _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_IGNORE
3461
35#endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
62#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
3663
3764#endif // _LIBCPP___ASSERTION_HANDLER
lib/libcxx/include/__atomic/atomic.h+36-60
......@@ -10,7 +10,9 @@
1010#define _LIBCPP___ATOMIC_ATOMIC_H
1111
1212#include <__atomic/atomic_sync.h>
13#include <__atomic/atomic_waitable_traits.h>
1314#include <__atomic/check_memory_order.h>
15#include <__atomic/floating_point_helper.h>
1416#include <__atomic/is_always_lock_free.h>
1517#include <__atomic/memory_order.h>
1618#include <__atomic/support.h>
......@@ -47,10 +49,10 @@ struct __atomic_base // false
4749 static constexpr bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value;
4850#endif
4951
50 _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const volatile _NOEXCEPT {
52 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const volatile _NOEXCEPT {
5153 return __cxx_atomic_is_lock_free(sizeof(__cxx_atomic_impl<_Tp>));
5254 }
53 _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const _NOEXCEPT {
55 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const _NOEXCEPT {
5456 return static_cast<__atomic_base const volatile*>(this)->is_lock_free();
5557 }
5658 _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
......@@ -61,11 +63,11 @@ struct __atomic_base // false
6163 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
6264 std::__cxx_atomic_store(std::addressof(__a_), __d, __m);
6365 }
64 _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
66 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
6567 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
6668 return std::__cxx_atomic_load(std::addressof(__a_), __m);
6769 }
68 _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
70 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
6971 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
7072 return std::__cxx_atomic_load(std::addressof(__a_), __m);
7173 }
......@@ -113,22 +115,16 @@ struct __atomic_base // false
113115 }
114116
115117#if _LIBCPP_STD_VER >= 20
116 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const
117 volatile _NOEXCEPT {
118 _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
118119 std::__atomic_wait(*this, __v, __m);
119120 }
120 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
121 wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
121 _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
122122 std::__atomic_wait(*this, __v, __m);
123123 }
124 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
125 std::__atomic_notify_one(*this);
126 }
127 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }
128 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
129 std::__atomic_notify_all(*this);
130 }
131 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }
124 _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { std::__atomic_notify_one(*this); }
125 _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }
126 _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { std::__atomic_notify_all(*this); }
127 _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }
132128#endif // _LIBCPP_STD_VER >= 20
133129
134130#if _LIBCPP_STD_VER >= 20
......@@ -205,12 +201,15 @@ struct __atomic_base<_Tp, true> : public __atomic_base<_Tp, false> {
205201 _LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __op) _NOEXCEPT { return fetch_xor(__op) ^ __op; }
206202};
207203
204#if _LIBCPP_STD_VER >= 20
208205// Here we need _IsIntegral because the default template argument is not enough
209206// e.g __atomic_base<int> is __atomic_base<int, true>, which inherits from
210207// __atomic_base<int, false> and the caller of the wait function is
211208// __atomic_base<int, false>. So specializing __atomic_base<_Tp> does not work
212209template <class _Tp, bool _IsIntegral>
213210struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > {
211 using __value_type _LIBCPP_NODEBUG = _Tp;
212
214213 static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_base<_Tp, _IsIntegral>& __a, memory_order __order) {
215214 return __a.load(__order);
216215 }
......@@ -231,6 +230,8 @@ struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > {
231230 }
232231};
233232
233#endif // _LIBCPP_STD_VER >= 20
234
234235template <typename _Tp>
235236struct __check_atomic_mandates {
236237 using type _LIBCPP_NODEBUG = _Tp;
......@@ -324,50 +325,26 @@ struct atomic<_Tp*> : public __atomic_base<_Tp*> {
324325 atomic& operator=(const atomic&) volatile = delete;
325326};
326327
328#if _LIBCPP_STD_VER >= 20
327329template <class _Tp>
328330struct __atomic_waitable_traits<atomic<_Tp> > : __atomic_waitable_traits<__atomic_base<_Tp> > {};
329331
330#if _LIBCPP_STD_VER >= 20
331332template <class _Tp>
332333 requires is_floating_point_v<_Tp>
333334struct atomic<_Tp> : __atomic_base<_Tp> {
334335private:
335 _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_fp80_long_double() {
336 // Only x87-fp80 long double has 64-bit mantissa
337 return __LDBL_MANT_DIG__ == 64 && std::is_same_v<_Tp, long double>;
338 }
339
340 _LIBCPP_HIDE_FROM_ABI static constexpr bool __has_rmw_builtin() {
341# ifndef _LIBCPP_COMPILER_CLANG_BASED
342 return false;
343# else
344 // The builtin __cxx_atomic_fetch_add errors during compilation for
345 // long double on platforms with fp80 format.
346 // For more details, see
347 // lib/Sema/SemaChecking.cpp function IsAllowedValueType
348 // LLVM Parser does not allow atomicrmw with x86_fp80 type.
349 // if (ValType->isSpecificBuiltinType(BuiltinType::LongDouble) &&
350 // &Context.getTargetInfo().getLongDoubleFormat() ==
351 // &llvm::APFloat::x87DoubleExtended())
352 // For more info
353 // https://github.com/llvm/llvm-project/issues/68602
354 // https://reviews.llvm.org/D53965
355 return !__is_fp80_long_double();
356# endif
357 }
358
359336 template <class _This, class _Operation, class _BuiltinOp>
360337 _LIBCPP_HIDE_FROM_ABI static _Tp
361338 __rmw_op(_This&& __self, _Tp __operand, memory_order __m, _Operation __operation, _BuiltinOp __builtin_op) {
362 if constexpr (__has_rmw_builtin()) {
339 if constexpr (std::__has_rmw_builtin<_Tp>()) {
363340 return __builtin_op(std::addressof(std::forward<_This>(__self).__a_), __operand, __m);
364341 } else {
365342 _Tp __old = __self.load(memory_order_relaxed);
366343 _Tp __new = __operation(__old, __operand);
367344 while (!__self.compare_exchange_weak(__old, __new, __m, memory_order_relaxed)) {
368345# ifdef _LIBCPP_COMPILER_CLANG_BASED
369 if constexpr (__is_fp80_long_double()) {
370 // https://github.com/llvm/llvm-project/issues/47978
346 if constexpr (std::__is_fp80_long_double<_Tp>()) {
347 // https://llvm.org/PR47978
371348 // clang bug: __old is not updated on failure for atomic<long double>::compare_exchange_weak
372349 // Note __old = __self.load(memory_order_relaxed) will not work
373350 std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), std::addressof(__old), memory_order_relaxed);
......@@ -462,12 +439,12 @@ public:
462439// atomic_is_lock_free
463440
464441template <class _Tp>
465_LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT {
442[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT {
466443 return __o->is_lock_free();
467444}
468445
469446template <class _Tp>
470_LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT {
447[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT {
471448 return __o->is_lock_free();
472449}
473450
......@@ -516,25 +493,25 @@ atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, me
516493// atomic_load
517494
518495template <class _Tp>
519_LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT {
496[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT {
520497 return __o->load();
521498}
522499
523500template <class _Tp>
524_LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const atomic<_Tp>* __o) _NOEXCEPT {
501[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const atomic<_Tp>* __o) _NOEXCEPT {
525502 return __o->load();
526503}
527504
528505// atomic_load_explicit
529506
530507template <class _Tp>
531_LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
532 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
508[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp
509atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
533510 return __o->load(__m);
534511}
535512
536513template <class _Tp>
537_LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
514[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
538515 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
539516 return __o->load(__m);
540517}
......@@ -642,28 +619,27 @@ _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit(
642619// atomic_wait
643620
644621template <class _Tp>
645_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
622_LIBCPP_HIDE_FROM_ABI void
646623atomic_wait(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT {
647624 return __o->wait(__v);
648625}
649626
650627template <class _Tp>
651_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
652atomic_wait(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT {
628_LIBCPP_HIDE_FROM_ABI void atomic_wait(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT {
653629 return __o->wait(__v);
654630}
655631
656632// atomic_wait_explicit
657633
658634template <class _Tp>
659_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
635_LIBCPP_HIDE_FROM_ABI void
660636atomic_wait_explicit(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT
661637 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
662638 return __o->wait(__v, __m);
663639}
664640
665641template <class _Tp>
666_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
642_LIBCPP_HIDE_FROM_ABI void
667643atomic_wait_explicit(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT
668644 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
669645 return __o->wait(__v, __m);
......@@ -672,22 +648,22 @@ atomic_wait_explicit(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __
672648// atomic_notify_one
673649
674650template <class _Tp>
675_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT {
651_LIBCPP_HIDE_FROM_ABI void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT {
676652 __o->notify_one();
677653}
678654template <class _Tp>
679_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT {
655_LIBCPP_HIDE_FROM_ABI void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT {
680656 __o->notify_one();
681657}
682658
683659// atomic_notify_all
684660
685661template <class _Tp>
686_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT {
662_LIBCPP_HIDE_FROM_ABI void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT {
687663 __o->notify_all();
688664}
689665template <class _Tp>
690_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT {
666_LIBCPP_HIDE_FROM_ABI void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT {
691667 __o->notify_all();
692668}
693669
lib/libcxx/include/__atomic/atomic_flag.h+19-37
......@@ -10,6 +10,7 @@
1010#define _LIBCPP___ATOMIC_ATOMIC_FLAG_H
1111
1212#include <__atomic/atomic_sync.h>
13#include <__atomic/atomic_waitable_traits.h>
1314#include <__atomic/contention_t.h>
1415#include <__atomic/memory_order.h>
1516#include <__atomic/support.h>
......@@ -49,22 +50,16 @@ struct atomic_flag {
4950 }
5051
5152#if _LIBCPP_STD_VER >= 20
52 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const
53 volatile _NOEXCEPT {
53 _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
5454 std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
5555 }
56 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
57 wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
56 _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
5857 std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
5958 }
60 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
61 std::__atomic_notify_one(*this);
62 }
63 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }
64 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
65 std::__atomic_notify_all(*this);
66 }
67 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }
59 _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { std::__atomic_notify_one(*this); }
60 _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }
61 _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { std::__atomic_notify_all(*this); }
62 _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }
6863#endif
6964
7065#if _LIBCPP_STD_VER >= 20
......@@ -80,8 +75,11 @@ struct atomic_flag {
8075 atomic_flag& operator=(const atomic_flag&) volatile = delete;
8176};
8277
78#if _LIBCPP_STD_VER >= 20
8379template <>
8480struct __atomic_waitable_traits<atomic_flag> {
81 using __value_type _LIBCPP_NODEBUG = _LIBCPP_ATOMIC_FLAG_TYPE;
82
8583 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE __atomic_load(const atomic_flag& __a, memory_order __order) {
8684 return std::__cxx_atomic_load(&__a.__a_, __order);
8785 }
......@@ -101,6 +99,7 @@ struct __atomic_waitable_traits<atomic_flag> {
10199 return std::addressof(__a.__a_);
102100 }
103101};
102#endif // _LIBCPP_STD_VER >= 20
104103
105104inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); }
106105
......@@ -143,43 +142,26 @@ inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, m
143142}
144143
145144#if _LIBCPP_STD_VER >= 20
146inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
147atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT {
145inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT {
148146 __o->wait(__v);
149147}
150148
151inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
152atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT {
153 __o->wait(__v);
154}
149inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT { __o->wait(__v); }
155150
156inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
151inline _LIBCPP_HIDE_FROM_ABI void
157152atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
158153 __o->wait(__v, __m);
159154}
160155
161inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
156inline _LIBCPP_HIDE_FROM_ABI void
162157atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
163158 __o->wait(__v, __m);
164159}
165160
166inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
167atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT {
168 __o->notify_one();
169}
170
171inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT {
172 __o->notify_one();
173}
174
175inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
176atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT {
177 __o->notify_all();
178}
179
180inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT {
181 __o->notify_all();
182}
161inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT { __o->notify_one(); }
162inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT { __o->notify_one(); }
163inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT { __o->notify_all(); }
164inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT { __o->notify_all(); }
183165#endif // _LIBCPP_STD_VER >= 20
184166
185167_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__atomic/atomic_ref.h+29-12
......@@ -19,7 +19,9 @@
1919
2020#include <__assert>
2121#include <__atomic/atomic_sync.h>
22#include <__atomic/atomic_waitable_traits.h>
2223#include <__atomic/check_memory_order.h>
24#include <__atomic/floating_point_helper.h>
2325#include <__atomic/memory_order.h>
2426#include <__atomic/to_gcc_order.h>
2527#include <__concepts/arithmetic.h>
......@@ -121,7 +123,9 @@ public:
121123 static constexpr bool is_always_lock_free =
122124 __atomic_always_lock_free(sizeof(_Tp), std::addressof(__get_aligner_instance<required_alignment>::__instance));
123125
124 _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const noexcept { return __atomic_is_lock_free(sizeof(_Tp), __ptr_); }
126 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const noexcept {
127 return __atomic_is_lock_free(sizeof(_Tp), __ptr_);
128 }
125129
126130 _LIBCPP_HIDE_FROM_ABI void store(_Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept
127131 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__order) {
......@@ -136,7 +140,7 @@ public:
136140 return __desired;
137141 }
138142
139 _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __order = memory_order::seq_cst) const noexcept
143 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __order = memory_order::seq_cst) const noexcept
140144 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__order) {
141145 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
142146 __order == memory_order::relaxed || __order == memory_order::consume || __order == memory_order::acquire ||
......@@ -219,6 +223,9 @@ public:
219223 }
220224 _LIBCPP_HIDE_FROM_ABI void notify_one() const noexcept { std::__atomic_notify_one(*this); }
221225 _LIBCPP_HIDE_FROM_ABI void notify_all() const noexcept { std::__atomic_notify_all(*this); }
226# if _LIBCPP_STD_VER >= 26
227 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp* address() const noexcept { return __ptr_; }
228# endif
222229
223230protected:
224231 using _Aligned_Tp [[__gnu__::__aligned__(required_alignment), __gnu__::__nodebug__]] = _Tp;
......@@ -229,6 +236,8 @@ protected:
229236
230237template <class _Tp>
231238struct __atomic_waitable_traits<__atomic_ref_base<_Tp>> {
239 using __value_type _LIBCPP_NODEBUG = _Tp;
240
232241 static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_ref_base<_Tp>& __a, memory_order __order) {
233242 return __a.load(__order);
234243 }
......@@ -322,20 +331,28 @@ struct atomic_ref<_Tp> : public __atomic_ref_base<_Tp> {
322331 atomic_ref& operator=(const atomic_ref&) = delete;
323332
324333 _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
325 _Tp __old = this->load(memory_order_relaxed);
326 _Tp __new = __old + __arg;
327 while (!this->compare_exchange_weak(__old, __new, __order, memory_order_relaxed)) {
328 __new = __old + __arg;
334 if constexpr (std::__has_rmw_builtin<_Tp>()) {
335 return __atomic_fetch_add(this->__ptr_, __arg, std::__to_gcc_order(__order));
336 } else {
337 _Tp __old = this->load(memory_order_relaxed);
338 _Tp __new = __old + __arg;
339 while (!this->compare_exchange_weak(__old, __new, __order, memory_order_relaxed)) {
340 __new = __old + __arg;
341 }
342 return __old;
329343 }
330 return __old;
331344 }
332345 _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
333 _Tp __old = this->load(memory_order_relaxed);
334 _Tp __new = __old - __arg;
335 while (!this->compare_exchange_weak(__old, __new, __order, memory_order_relaxed)) {
336 __new = __old - __arg;
346 if constexpr (std::__has_rmw_builtin<_Tp>()) {
347 return __atomic_fetch_sub(this->__ptr_, __arg, std::__to_gcc_order(__order));
348 } else {
349 _Tp __old = this->load(memory_order_relaxed);
350 _Tp __new = __old - __arg;
351 while (!this->compare_exchange_weak(__old, __new, __order, memory_order_relaxed)) {
352 __new = __old - __arg;
353 }
354 return __old;
337355 }
338 return __old;
339356 }
340357
341358 _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __arg) const noexcept { return fetch_add(__arg) + __arg; }
lib/libcxx/include/__atomic/atomic_sync.h+127-55
......@@ -9,6 +9,7 @@
99#ifndef _LIBCPP___ATOMIC_ATOMIC_SYNC_H
1010#define _LIBCPP___ATOMIC_ATOMIC_SYNC_H
1111
12#include <__atomic/atomic_waitable_traits.h>
1213#include <__atomic/contention_t.h>
1314#include <__atomic/memory_order.h>
1415#include <__atomic/to_gcc_order.h>
......@@ -19,6 +20,7 @@
1920#include <__type_traits/conjunction.h>
2021#include <__type_traits/decay.h>
2122#include <__type_traits/invoke.h>
23#include <__type_traits/is_same.h>
2224#include <__type_traits/void_t.h>
2325#include <__utility/declval.h>
2426#include <cstring>
......@@ -29,50 +31,89 @@
2931
3032_LIBCPP_BEGIN_NAMESPACE_STD
3133
32// The customisation points to enable the following functions:
33// - __atomic_wait
34// - __atomic_wait_unless
35// - __atomic_notify_one
36// - __atomic_notify_all
37// Note that std::atomic<T>::wait was back-ported to C++03
38// The below implementations look ugly to support C++03
39template <class _Tp, class = void>
40struct __atomic_waitable_traits {
41 template <class _AtomicWaitable>
42 static void __atomic_load(_AtomicWaitable&&, memory_order) = delete;
43
44 template <class _AtomicWaitable>
45 static void __atomic_contention_address(_AtomicWaitable&&) = delete;
46};
47
48template <class _Tp, class = void>
49struct __atomic_waitable : false_type {};
50
51template <class _Tp>
52struct __atomic_waitable< _Tp,
53 __void_t<decltype(__atomic_waitable_traits<__decay_t<_Tp> >::__atomic_load(
54 std::declval<const _Tp&>(), std::declval<memory_order>())),
55 decltype(__atomic_waitable_traits<__decay_t<_Tp> >::__atomic_contention_address(
56 std::declval<const _Tp&>()))> > : true_type {};
57
5834#if _LIBCPP_STD_VER >= 20
5935# if _LIBCPP_HAS_THREADS
6036
61_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*) _NOEXCEPT;
62_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*) _NOEXCEPT;
63_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
64__libcpp_atomic_monitor(void const volatile*) _NOEXCEPT;
65_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
66__libcpp_atomic_wait(void const volatile*, __cxx_contention_t) _NOEXCEPT;
67
68_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
69__cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
70_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
71__cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
72_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
37# if !_LIBCPP_AVAILABILITY_HAS_NEW_SYNC
38
39// old dylib interface kept for backwards compatibility
40_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*) _NOEXCEPT;
41_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*) _NOEXCEPT;
42_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*) _NOEXCEPT;
43_LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t) _NOEXCEPT;
44
45_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
46_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
47_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
7348__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
74_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
49_LIBCPP_EXPORTED_FROM_ABI void
7550__libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t) _NOEXCEPT;
51# endif // !_LIBCPP_AVAILABILITY_HAS_NEW_SYNC
52
53// new dylib interface
54
55// return the global contention state's current value for the address
56_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
57__atomic_monitor_global(void const* __address) _NOEXCEPT;
58
59// wait on the global contention state to be changed from the given value for the address
60_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void
61__atomic_wait_global_table(void const* __address, __cxx_contention_t __monitor_value) _NOEXCEPT;
62
63// notify one waiter waiting on the global contention state for the address
64_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_global_table(void const*) _NOEXCEPT;
65
66// notify all waiters waiting on the global contention state for the address
67_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_global_table(void const*) _NOEXCEPT;
68
69// wait on the address directly with the native platform wait
70template <std::size_t _Size>
71_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void
72__atomic_wait_native(void const* __address, void const* __old_value) _NOEXCEPT;
73
74// notify one waiter waiting on the address directly with the native platform wait
75template <std::size_t _Size>
76_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_native(const void*) _NOEXCEPT;
77
78// notify all waiters waiting on the address directly with the native platform wait
79template <std::size_t _Size>
80_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native(const void*) _NOEXCEPT;
81
82# if _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
83
84template <class _AtomicWaitable, class _Poll>
85struct __atomic_wait_backoff_impl {
86 const _AtomicWaitable& __a_;
87 _Poll __poll_;
88 memory_order __order_;
89
90 using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
91 using __value_type _LIBCPP_NODEBUG = typename __waitable_traits::__value_type;
92
93 _LIBCPP_HIDE_FROM_ABI __backoff_results operator()(chrono::nanoseconds __elapsed) const {
94 if (__elapsed > chrono::microseconds(4)) {
95 auto __contention_address = const_cast<const void*>(
96 static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a_)));
97
98 if constexpr (__has_native_atomic_wait<__value_type>) {
99 auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_);
100 if (__poll_(__atomic_value))
101 return __backoff_results::__poll_success;
102 std::__atomic_wait_native<sizeof(__value_type)>(__contention_address, std::addressof(__atomic_value));
103 } else {
104 __cxx_contention_t __monitor_val = std::__atomic_monitor_global(__contention_address);
105 auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_);
106 if (__poll_(__atomic_value))
107 return __backoff_results::__poll_success;
108 std::__atomic_wait_global_table(__contention_address, __monitor_val);
109 }
110 } else {
111 } // poll
112 return __backoff_results::__continue_poll;
113 }
114};
115
116# else // _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
76117
77118template <class _AtomicWaitable, class _Poll>
78119struct __atomic_wait_backoff_impl {
......@@ -82,7 +123,6 @@ struct __atomic_wait_backoff_impl {
82123
83124 using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
84125
85 _LIBCPP_AVAILABILITY_SYNC
86126 _LIBCPP_HIDE_FROM_ABI bool
87127 __update_monitor_val_and_poll(__cxx_atomic_contention_t const volatile*, __cxx_contention_t& __monitor_val) const {
88128 // In case the contention type happens to be __cxx_atomic_contention_t, i.e. __cxx_atomic_impl<int64_t>,
......@@ -95,7 +135,6 @@ struct __atomic_wait_backoff_impl {
95135 return __poll_(__monitor_val);
96136 }
97137
98 _LIBCPP_AVAILABILITY_SYNC
99138 _LIBCPP_HIDE_FROM_ABI bool
100139 __update_monitor_val_and_poll(void const volatile* __contention_address, __cxx_contention_t& __monitor_val) const {
101140 // In case the contention type is anything else, platform wait is monitoring a __cxx_atomic_contention_t
......@@ -105,20 +144,21 @@ struct __atomic_wait_backoff_impl {
105144 return __poll_(__current_val);
106145 }
107146
108 _LIBCPP_AVAILABILITY_SYNC
109 _LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const {
147 _LIBCPP_HIDE_FROM_ABI __backoff_results operator()(chrono::nanoseconds __elapsed) const {
110148 if (__elapsed > chrono::microseconds(4)) {
111149 auto __contention_address = __waitable_traits::__atomic_contention_address(__a_);
112150 __cxx_contention_t __monitor_val;
113151 if (__update_monitor_val_and_poll(__contention_address, __monitor_val))
114 return true;
152 return __backoff_results::__poll_success;
115153 std::__libcpp_atomic_wait(__contention_address, __monitor_val);
116154 } else {
117155 } // poll
118 return false;
156 return __backoff_results::__continue_poll;
119157 }
120158};
121159
160# endif // _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
161
122162// The semantics of this function are similar to `atomic`'s
123163// `.wait(T old, std::memory_order order)`, but instead of having a hardcoded
124164// predicate (is the loaded value unequal to `old`?), the predicate function is
......@@ -128,9 +168,8 @@ struct __atomic_wait_backoff_impl {
128168// `false`, it must set the argument to its current understanding of the atomic
129169// value. The predicate function must not return `false` spuriously.
130170template <class _AtomicWaitable, class _Poll>
131_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
132__atomic_wait_unless(const _AtomicWaitable& __a, memory_order __order, _Poll&& __poll) {
133 static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
171_LIBCPP_HIDE_FROM_ABI void __atomic_wait_unless(const _AtomicWaitable& __a, memory_order __order, _Poll&& __poll) {
172 static_assert(__atomic_waitable<_AtomicWaitable>);
134173 __atomic_wait_backoff_impl<_AtomicWaitable, __decay_t<_Poll> > __backoff_fn = {__a, __poll, __order};
135174 std::__libcpp_thread_poll_with_backoff(
136175 /* poll */
......@@ -141,18 +180,52 @@ __atomic_wait_unless(const _AtomicWaitable& __a, memory_order __order, _Poll&& _
141180 /* backoff */ __backoff_fn);
142181}
143182
183# if _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
184
144185template <class _AtomicWaitable>
145_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable& __a) {
146 static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
186_LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable& __a) {
187 static_assert(__atomic_waitable<_AtomicWaitable>);
188 using __value_type _LIBCPP_NODEBUG = typename __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__value_type;
189 using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
190 auto __contention_address =
191 const_cast<const void*>(static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a)));
192 if constexpr (__has_native_atomic_wait<__value_type>) {
193 std::__atomic_notify_one_native<sizeof(__value_type)>(__contention_address);
194 } else {
195 std::__atomic_notify_one_global_table(__contention_address);
196 }
197}
198
199template <class _AtomicWaitable>
200_LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable& __a) {
201 static_assert(__atomic_waitable<_AtomicWaitable>);
202 using __value_type _LIBCPP_NODEBUG = typename __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__value_type;
203 using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
204 auto __contention_address =
205 const_cast<const void*>(static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a)));
206 if constexpr (__has_native_atomic_wait<__value_type>) {
207 std::__atomic_notify_all_native<sizeof(__value_type)>(__contention_address);
208 } else {
209 std::__atomic_notify_all_global_table(__contention_address);
210 }
211}
212
213# else // _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
214
215template <class _AtomicWaitable>
216_LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable& __a) {
217 static_assert(__atomic_waitable<_AtomicWaitable>);
147218 std::__cxx_atomic_notify_one(__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a));
148219}
149220
150221template <class _AtomicWaitable>
151_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable& __a) {
152 static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
222_LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable& __a) {
223 static_assert(__atomic_waitable<_AtomicWaitable>);
153224 std::__cxx_atomic_notify_all(__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a));
154225}
155226
227# endif
228
156229# else // _LIBCPP_HAS_THREADS
157230
158231template <class _AtomicWaitable, class _Poll>
......@@ -180,9 +253,8 @@ _LIBCPP_HIDE_FROM_ABI bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp c
180253}
181254
182255template <class _AtomicWaitable, class _Tp>
183_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
184__atomic_wait(_AtomicWaitable& __a, _Tp __val, memory_order __order) {
185 static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
256_LIBCPP_HIDE_FROM_ABI void __atomic_wait(_AtomicWaitable& __a, _Tp __val, memory_order __order) {
257 static_assert(__atomic_waitable<_AtomicWaitable>);
186258 std::__atomic_wait_unless(__a, __order, [&](_Tp const& __current) {
187259 return !std::__cxx_nonatomic_compare_equal(__current, __val);
188260 });
lib/libcxx/include/__atomic/atomic_sync_timed.h created+144
......@@ -0,0 +1,144 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_ATOMIC_SYNC_TIMED_H
10#define _LIBCPP___ATOMIC_ATOMIC_SYNC_TIMED_H
11
12#include <__atomic/atomic_waitable_traits.h>
13#include <__atomic/contention_t.h>
14#include <__atomic/memory_order.h>
15#include <__atomic/to_gcc_order.h>
16#include <__chrono/duration.h>
17#include <__config>
18#include <__memory/addressof.h>
19#include <__thread/poll_with_backoff.h>
20#include <__thread/timed_backoff_policy.h>
21#include <__type_traits/conjunction.h>
22#include <__type_traits/decay.h>
23#include <__type_traits/has_unique_object_representation.h>
24#include <__type_traits/invoke.h>
25#include <__type_traits/is_same.h>
26#include <__type_traits/is_trivially_copyable.h>
27#include <__type_traits/void_t.h>
28#include <__utility/declval.h>
29#include <cstdint>
30#include <cstring>
31
32#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
33# pragma GCC system_header
34#endif
35
36_LIBCPP_BEGIN_NAMESPACE_STD
37
38#if _LIBCPP_STD_VER >= 20
39# if _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
40
41_LIBCPP_AVAILABILITY_NEW_SYNC
42_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __atomic_monitor_global(void const* __address) _NOEXCEPT;
43
44// wait on the global contention state to be changed from the given value for the address
45_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_global_table_with_timeout(
46 void const* __address, __cxx_contention_t __monitor_value, uint64_t __timeout_ns) _NOEXCEPT;
47
48// wait on the address directly with the native platform wait
49template <std::size_t _Size>
50_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void
51__atomic_wait_native_with_timeout(void const* __address, void const* __old_value, uint64_t __timeout_ns) _NOEXCEPT;
52
53template <class _AtomicWaitable, class _Poll, class _Rep, class _Period>
54struct __atomic_wait_timed_backoff_impl {
55 const _AtomicWaitable& __a_;
56 _Poll __poll_;
57 memory_order __order_;
58 chrono::duration<_Rep, _Period> __rel_time_;
59
60 using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
61 using __value_type _LIBCPP_NODEBUG = typename __waitable_traits::__value_type;
62
63 _LIBCPP_HIDE_FROM_ABI __backoff_results operator()(chrono::nanoseconds __elapsed) const {
64 if (__elapsed > chrono::microseconds(4)) {
65 auto __contention_address = const_cast<const void*>(
66 static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a_)));
67
68 uint64_t __timeout_ns =
69 static_cast<uint64_t>((chrono::duration_cast<chrono::nanoseconds>(__rel_time_) - __elapsed).count());
70
71 if constexpr (__has_native_atomic_wait<__value_type>) {
72 auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_);
73 if (__poll_(__atomic_value))
74 return __backoff_results::__poll_success;
75 std::__atomic_wait_native_with_timeout<sizeof(__value_type)>(
76 __contention_address, std::addressof(__atomic_value), __timeout_ns);
77 } else {
78 __cxx_contention_t __monitor_val = std::__atomic_monitor_global(__contention_address);
79 auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_);
80 if (__poll_(__atomic_value))
81 return __backoff_results::__poll_success;
82 std::__atomic_wait_global_table_with_timeout(__contention_address, __monitor_val, __timeout_ns);
83 }
84 } else {
85 } // poll
86 return __backoff_results::__continue_poll;
87 }
88};
89
90// The semantics of this function are similar to `atomic`'s
91// `.wait(T old, std::memory_order order)` with a timeout, but instead of having a hardcoded
92// predicate (is the loaded value unequal to `old`?), the predicate function is
93// specified as an argument. The loaded value is given as an in-out argument to
94// the predicate. If the predicate function returns `true`,
95// `__atomic_wait_unless_with_timeout` will return. If the predicate function returns
96// `false`, it must set the argument to its current understanding of the atomic
97// value. The predicate function must not return `false` spuriously.
98template <class _AtomicWaitable, class _Poll, class _Rep, class _Period>
99_LIBCPP_HIDE_FROM_ABI bool __atomic_wait_unless_with_timeout(
100 const _AtomicWaitable& __a,
101 memory_order __order,
102 _Poll&& __poll,
103 chrono::duration<_Rep, _Period> const& __rel_time) {
104 static_assert(__atomic_waitable<_AtomicWaitable>, "");
105 __atomic_wait_timed_backoff_impl<_AtomicWaitable, __decay_t<_Poll>, _Rep, _Period> __backoff_fn = {
106 __a, __poll, __order, __rel_time};
107 auto __poll_result = std::__libcpp_thread_poll_with_backoff(
108 /* poll */
109 [&]() {
110 auto __current_val = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_load(__a, __order);
111 return __poll(__current_val);
112 },
113 /* backoff */ __backoff_fn,
114 __rel_time);
115
116 return __poll_result == __poll_with_backoff_results::__poll_success;
117}
118
119# elif _LIBCPP_HAS_THREADS // _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
120
121template <class _AtomicWaitable, class _Poll, class _Rep, class _Period>
122_LIBCPP_HIDE_FROM_ABI bool __atomic_wait_unless_with_timeout(
123 const _AtomicWaitable& __a,
124 memory_order __order,
125 _Poll&& __poll,
126 chrono::duration<_Rep, _Period> const& __rel_time) {
127 auto __res = std::__libcpp_thread_poll_with_backoff(
128 /* poll */
129 [&]() {
130 auto __current_val = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_load(__a, __order);
131 return __poll(__current_val);
132 },
133 /* backoff */ __libcpp_timed_backoff_policy(),
134 __rel_time);
135 return __res == __poll_with_backoff_results::__poll_success;
136}
137
138# endif // _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
139
140#endif // C++20
141
142_LIBCPP_END_NAMESPACE_STD
143
144#endif // _LIBCPP___ATOMIC_ATOMIC_SYNC_TIMED_H
lib/libcxx/include/__atomic/atomic_waitable_traits.h created+103
......@@ -0,0 +1,103 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_ATOMIC_WAITABLE_TRAITS_H
10#define _LIBCPP___ATOMIC_ATOMIC_WAITABLE_TRAITS_H
11
12#include <__atomic/contention_t.h>
13#include <__atomic/memory_order.h>
14#include <__config>
15#include <__type_traits/decay.h>
16#include <__type_traits/has_unique_object_representation.h>
17#include <__type_traits/is_same.h>
18#include <__type_traits/is_trivially_copyable.h>
19#include <__type_traits/void_t.h>
20#include <__utility/declval.h>
21#include <cstring>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24# pragma GCC system_header
25#endif
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29#if _LIBCPP_STD_VER >= 20
30
31// The customisation points to enable the following functions:
32// - __atomic_wait
33// - __atomic_wait_unless
34// - __atomic_notify_one
35// - __atomic_notify_all
36template <class _Tp, class = void>
37struct __atomic_waitable_traits {
38 using __value_type _LIBCPP_NODEBUG = void;
39
40 template <class _AtomicWaitable>
41 static void __atomic_load(_AtomicWaitable&&, memory_order) = delete;
42
43 template <class _AtomicWaitable>
44 static void __atomic_contention_address(_AtomicWaitable&&) = delete;
45};
46
47template <class _Tp>
48concept __atomic_waitable = requires(const _Tp __t, memory_order __order) {
49 typename __atomic_waitable_traits<__decay_t<_Tp> >::__value_type;
50 { __atomic_waitable_traits<__decay_t<_Tp> >::__atomic_load(__t, __order) };
51 { __atomic_waitable_traits<__decay_t<_Tp> >::__atomic_contention_address(__t) };
52};
53
54# ifdef __linux__
55# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(4)
56# elif defined(__APPLE__)
57# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) \
58 _APPLY(4) \
59 _APPLY(8)
60# elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
61# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(8)
62# elif defined(_WIN32)
63# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(8)
64# else
65# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(sizeof(__cxx_contention_t))
66# endif // __linux__
67
68// concepts defines the types are supported natively by the platform's wait
69
70# if defined(_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE)
71
72template <class _Tp>
73_LIBCPP_HIDE_FROM_ABI constexpr bool __has_native_atomic_wait_impl() {
74 if (alignof(_Tp) % sizeof(_Tp) != 0)
75 return false;
76 switch (sizeof(_Tp)) {
77# define _LIBCPP_MAKE_CASE(n) \
78 case n: \
79 return true;
80 _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_LIBCPP_MAKE_CASE)
81 default:
82 return false;
83# undef _LIBCPP_MAKE_CASE
84 };
85}
86
87template <class _Tp>
88concept __has_native_atomic_wait =
89 has_unique_object_representations_v<_Tp> && is_trivially_copyable_v<_Tp> &&
90 std::__has_native_atomic_wait_impl<_Tp>();
91
92# else // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
93
94template <class _Tp>
95concept __has_native_atomic_wait = is_same_v<_Tp, __cxx_contention_t>;
96
97# endif // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
98
99#endif // C++20
100
101_LIBCPP_END_NAMESPACE_STD
102
103#endif // _LIBCPP___ATOMIC_ATOMIC_WAITABLE_TRAITS_H
lib/libcxx/include/__atomic/contention_t.h+27-3
......@@ -19,11 +19,35 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
22// The original definition of `__cxx_contention_t` seemed a bit arbitrary.
23// When we enable the _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE ABI,
24// use definitions that are based on what the underlying platform supports
25// instead.
26#if defined(_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE)
27
28# ifdef __linux__
29using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
30# elif defined(__APPLE__)
31using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
32# elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
33using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
34# elif defined(_AIX) && !defined(__64BIT__)
35using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
36# elif defined(_WIN32)
37using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
38# else
39using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
40# endif // __linux__
41
42#else // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
43
44# if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
2345using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
24#else
46# else
2547using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
26#endif // __linux__ || (_AIX && !__64BIT__)
48# endif // __linux__ || (_AIX && !__64BIT__)
49
50#endif // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
2751
2852using __cxx_atomic_contention_t _LIBCPP_NODEBUG = __cxx_atomic_impl<__cxx_contention_t>;
2953
lib/libcxx/include/__atomic/floating_point_helper.h created+55
......@@ -0,0 +1,55 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ATOMIC_FLOATING_POINT_HELPER_H
10#define _LIBCPP___ATOMIC_FLOATING_POINT_HELPER_H
11
12#include <__config>
13#include <__type_traits/is_floating_point.h>
14#include <__type_traits/is_same.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22#if _LIBCPP_STD_VER >= 20
23
24template <class _Tp>
25_LIBCPP_HIDE_FROM_ABI constexpr bool __is_fp80_long_double() {
26 // Only x87-fp80 long double has 64-bit mantissa
27 return __LDBL_MANT_DIG__ == 64 && std::is_same_v<_Tp, long double>;
28}
29
30template <class _Tp>
31_LIBCPP_HIDE_FROM_ABI constexpr bool __has_rmw_builtin() {
32 static_assert(std::is_floating_point_v<_Tp>);
33# ifndef _LIBCPP_COMPILER_CLANG_BASED
34 return false;
35# else
36 // The builtin __cxx_atomic_fetch_add errors during compilation for
37 // long double on platforms with fp80 format.
38 // For more details, see
39 // lib/Sema/SemaChecking.cpp function IsAllowedValueType
40 // LLVM Parser does not allow atomicrmw with x86_fp80 type.
41 // if (ValType->isSpecificBuiltinType(BuiltinType::LongDouble) &&
42 // &Context.getTargetInfo().getLongDoubleFormat() ==
43 // &llvm::APFloat::x87DoubleExtended())
44 // For more info
45 // https://llvm.org/PR68602
46 // https://reviews.llvm.org/D53965
47 return !std::__is_fp80_long_double<_Tp>();
48# endif
49}
50
51#endif
52
53_LIBCPP_END_NAMESPACE_STD
54
55#endif // _LIBCPP___ATOMIC_FLOATING_POINT_HELPER_H
lib/libcxx/include/__bit/countl.h+1-2
......@@ -24,7 +24,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2424
2525template <class _Tp>
2626_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countl_zero(_Tp __t) _NOEXCEPT {
27 static_assert(__is_unsigned_integer_v<_Tp>, "__countl_zero requires an unsigned integer type");
2827 return __builtin_clzg(__t, numeric_limits<_Tp>::digits);
2928}
3029
......@@ -37,7 +36,7 @@ template <__unsigned_integer _Tp>
3736
3837template <__unsigned_integer _Tp>
3938[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept {
40 return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
39 return std::countl_zero(static_cast<_Tp>(~__t));
4140}
4241
4342#endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/__bit/countr.h+1-2
......@@ -24,7 +24,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2424
2525template <class _Tp>
2626[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __countr_zero(_Tp __t) _NOEXCEPT {
27 static_assert(__is_unsigned_integer_v<_Tp>, "__countr_zero only works with unsigned types");
2827 return __builtin_ctzg(__t, numeric_limits<_Tp>::digits);
2928}
3029
......@@ -37,7 +36,7 @@ template <__unsigned_integer _Tp>
3736
3837template <__unsigned_integer _Tp>
3938[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {
40 return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
39 return std::countr_zero(static_cast<_Tp>(~__t));
4140}
4241
4342#endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/__bit/has_single_bit.h+1-1
......@@ -25,7 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2525
2626template <__unsigned_integer _Tp>
2727[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
28 return __t != 0 && (((__t & (__t - 1)) == 0));
28 return __builtin_popcountg(__t) == 1;
2929}
3030
3131_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__bit/popcount.h-1
......@@ -23,7 +23,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2323
2424template <class _Tp>
2525[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __popcount(_Tp __t) _NOEXCEPT {
26 static_assert(__is_unsigned_integer_v<_Tp>, "__popcount only works with unsigned types");
2726 return __builtin_popcountg(__t);
2827}
2928
lib/libcxx/include/__bit/rotate.h+15-26
......@@ -22,46 +22,35 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222// Writing two full functions for rotl and rotr makes it easier for the compiler
2323// to optimize the code. On x86 this function becomes the ROL instruction and
2424// the rotr function becomes the ROR instruction.
25template <class _Tp>
26_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotl(_Tp __x, int __s) _NOEXCEPT {
27 static_assert(__is_unsigned_integer_v<_Tp>, "__rotl requires an unsigned integer type");
25
26#if _LIBCPP_STD_VER >= 20
27
28template <__unsigned_integer _Tp>
29[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, int __cnt) noexcept {
2830 const int __n = numeric_limits<_Tp>::digits;
29 int __r = __s % __n;
31 int __r = __cnt % __n;
3032
3133 if (__r == 0)
32 return __x;
34 return __t;
3335
3436 if (__r > 0)
35 return (__x << __r) | (__x >> (__n - __r));
37 return (__t << __r) | (__t >> (__n - __r));
3638
37 return (__x >> -__r) | (__x << (__n + __r));
39 return (__t >> -__r) | (__t << (__n + __r));
3840}
3941
40template <class _Tp>
41_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotr(_Tp __x, int __s) _NOEXCEPT {
42 static_assert(__is_unsigned_integer_v<_Tp>, "__rotr requires an unsigned integer type");
42template <__unsigned_integer _Tp>
43[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, int __cnt) noexcept {
4344 const int __n = numeric_limits<_Tp>::digits;
44 int __r = __s % __n;
45 int __r = __cnt % __n;
4546
4647 if (__r == 0)
47 return __x;
48 return __t;
4849
4950 if (__r > 0)
50 return (__x >> __r) | (__x << (__n - __r));
51
52 return (__x << -__r) | (__x >> (__n + __r));
53}
51 return (__t >> __r) | (__t << (__n - __r));
5452
55#if _LIBCPP_STD_VER >= 20
56
57template <__unsigned_integer _Tp>
58[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, int __cnt) noexcept {
59 return std::__rotl(__t, __cnt);
60}
61
62template <__unsigned_integer _Tp>
63[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, int __cnt) noexcept {
64 return std::__rotr(__t, __cnt);
53 return (__t << -__r) | (__t >> (__n + __r));
6554}
6655
6756#endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/__bit_reference+207-18
......@@ -15,8 +15,10 @@
1515#include <__algorithm/copy_backward.h>
1616#include <__algorithm/copy_n.h>
1717#include <__algorithm/equal.h>
18#include <__algorithm/fill_n.h>
1819#include <__algorithm/min.h>
1920#include <__algorithm/rotate.h>
21#include <__algorithm/specialized_algorithms.h>
2022#include <__algorithm/swap_ranges.h>
2123#include <__assert>
2224#include <__bit/countr.h>
......@@ -137,7 +139,7 @@ public:
137139 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT {
138140 return static_cast<bool>(*__seg_ & __mask_);
139141 }
140 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT {
142 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT {
141143 return !static_cast<bool>(*this);
142144 }
143145
......@@ -307,6 +309,15 @@ public:
307309 {
308310 }
309311
312#ifdef _LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR
313 template <bool _IsConstDep = _IsConst, __enable_if_t<_IsConstDep, int> = 0>
314 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
315 : __seg_(__it.__seg_),
316 __ctz_(__it.__ctz_) {}
317
318 _LIBCPP_HIDE_FROM_ABI __bit_iterator(const __bit_iterator&) = default;
319 _LIBCPP_HIDE_FROM_ABI __bit_iterator& operator=(const __bit_iterator&) = default;
320#else
310321 // When _IsConst=false, this is the copy constructor.
311322 // It is non-trivial. Making it trivial would break ABI.
312323 // When _IsConst=true, this is a converting constructor;
......@@ -327,6 +338,7 @@ public:
327338 __ctz_ = __it.__ctz_;
328339 return *this;
329340 }
341#endif
330342
331343 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT {
332344 _LIBCPP_ASSERT_INTERNAL(__ctz_ < __bits_per_word, "Dereferencing an invalid __bit_iterator.");
......@@ -467,20 +479,6 @@ private:
467479 template <class _Dp>
468480 friend struct __bit_array;
469481
470 template <bool _FillVal, class _Dp>
471 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend void
472 __fill_n_bool(__bit_iterator<_Dp, false> __first, typename __size_difference_type_traits<_Dp>::size_type __n);
473
474 template <class _Dp, bool _IC>
475 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_aligned(
476 __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
477 template <class _Dp, bool _IC>
478 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_unaligned(
479 __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
480 template <class _Dp, bool _IC>
481 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend pair<__bit_iterator<_Dp, _IC>, __bit_iterator<_Dp, false> >
482 __copy_impl::operator()(
483 __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result) const;
484482 template <class _Dp, bool _IC>
485483 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_aligned(
486484 __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
......@@ -511,10 +509,20 @@ private:
511509 bool _IsConst1,
512510 bool _IsConst2,
513511 class _BinaryPredicate,
514 __enable_if_t<__desugars_to_v<__equal_tag, _BinaryPredicate, bool, bool>, int> >
512 class _Proj1,
513 class _Proj2,
514 __enable_if_t<__is_identity<_Proj1>::value && __is_identity<_Proj2>::value &&
515 __desugars_to_v<__equal_tag, _BinaryPredicate, bool, bool>,
516 int> >
515517 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool __equal_iter_impl(
516 __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst2>, _BinaryPredicate);
517 template <class _Dp,
518 __bit_iterator<_Dp, _IsConst1>,
519 __bit_iterator<_Dp, _IsConst1>,
520 __bit_iterator<_Dp, _IsConst2>,
521 _BinaryPredicate,
522 _Proj1&,
523 _Proj2&);
524 template <bool,
525 class _Dp,
518526 bool _IsConst1,
519527 bool _IsConst2,
520528 class _Pred,
......@@ -537,6 +545,187 @@ private:
537545 template <bool _ToCount, class _Dp, bool _IC>
538546 friend typename __bit_iterator<_Dp, _IC>::difference_type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
539547 __count_bool(__bit_iterator<_Dp, _IC>, typename __size_difference_type_traits<_Dp>::size_type);
548
549 template <class, class...>
550 friend struct __specialized_algorithm;
551};
552
553template <class _Cp>
554struct __specialized_algorithm<_Algorithm::__fill_n, __single_iterator<__bit_iterator<_Cp, false> > > {
555 static const bool __has_algorithm = true;
556
557 template <bool _FillVal>
558 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void
559 __impl(__bit_iterator<_Cp, false> __first, typename __size_difference_type_traits<_Cp>::size_type __n) {
560 using _It = __bit_iterator<_Cp, false>;
561 using __storage_type = typename _It::__storage_type;
562
563 const int __bits_per_word = _It::__bits_per_word;
564 // do first partial word
565 if (__first.__ctz_ != 0) {
566 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
567 __storage_type __dn = std::min(__clz_f, __n);
568 std::__fill_masked_range(std::__to_address(__first.__seg_), __clz_f - __dn, __first.__ctz_, _FillVal);
569 __n -= __dn;
570 ++__first.__seg_;
571 }
572 // do middle whole words
573 __storage_type __nw = __n / __bits_per_word;
574 std::__fill_n(std::__to_address(__first.__seg_), __nw, _FillVal ? static_cast<__storage_type>(-1) : 0);
575 __n -= __nw * __bits_per_word;
576 // do last partial word
577 if (__n > 0) {
578 __first.__seg_ += __nw;
579 std::__fill_masked_range(std::__to_address(__first.__seg_), __bits_per_word - __n, 0u, _FillVal);
580 }
581 }
582
583 template <class _Size, class _Tp>
584 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static __bit_iterator<_Cp, false>
585 operator()(__bit_iterator<_Cp, false> __first, _Size __n, const _Tp& __value) {
586 if (__n > 0) {
587 if (__value)
588 __impl<true>(__first, __n);
589 else
590 __impl<false>(__first, __n);
591 }
592 return __first + __n;
593 }
594};
595
596template <class _Cp, bool _IsConst>
597struct __specialized_algorithm<_Algorithm::__copy,
598 __iterator_pair<__bit_iterator<_Cp, _IsConst>, __bit_iterator<_Cp, _IsConst> >,
599 __single_iterator<__bit_iterator<_Cp, false> > > {
600 static const bool __has_algorithm = true;
601
602 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static __bit_iterator<_Cp, false>
603 __aligned_impl(__bit_iterator<_Cp, _IsConst> __first,
604 __bit_iterator<_Cp, _IsConst> __last,
605 __bit_iterator<_Cp, false> __result) {
606 using _In = __bit_iterator<_Cp, _IsConst>;
607 using difference_type = typename _In::difference_type;
608 using __storage_type = typename _In::__storage_type;
609
610 const int __bits_per_word = _In::__bits_per_word;
611 difference_type __n = __last - __first;
612 if (__n > 0) {
613 // do first word
614 if (__first.__ctz_ != 0) {
615 unsigned __clz = __bits_per_word - __first.__ctz_;
616 difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
617 __n -= __dn;
618 __storage_type __m = std::__middle_mask<__storage_type>(__clz - __dn, __first.__ctz_);
619 __storage_type __b = *__first.__seg_ & __m;
620 *__result.__seg_ &= ~__m;
621 *__result.__seg_ |= __b;
622 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
623 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
624 ++__first.__seg_;
625 // __first.__ctz_ = 0;
626 }
627 // __first.__ctz_ == 0;
628 // do middle words
629 __storage_type __nw = __n / __bits_per_word;
630 std::copy(std::__to_address(__first.__seg_),
631 std::__to_address(__first.__seg_ + __nw),
632 std::__to_address(__result.__seg_));
633 __n -= __nw * __bits_per_word;
634 __result.__seg_ += __nw;
635 // do last word
636 if (__n > 0) {
637 __first.__seg_ += __nw;
638 __storage_type __m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
639 __storage_type __b = *__first.__seg_ & __m;
640 *__result.__seg_ &= ~__m;
641 *__result.__seg_ |= __b;
642 __result.__ctz_ = static_cast<unsigned>(__n);
643 }
644 }
645 return __result;
646 }
647
648 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static __bit_iterator<_Cp, false>
649 __unaligned_impl(__bit_iterator<_Cp, _IsConst> __first,
650 __bit_iterator<_Cp, _IsConst> __last,
651 __bit_iterator<_Cp, false> __result) {
652 using _In = __bit_iterator<_Cp, _IsConst>;
653 using difference_type = typename _In::difference_type;
654 using __storage_type = typename _In::__storage_type;
655
656 const int __bits_per_word = _In::__bits_per_word;
657 difference_type __n = __last - __first;
658 if (__n > 0) {
659 // do first word
660 if (__first.__ctz_ != 0) {
661 unsigned __clz_f = __bits_per_word - __first.__ctz_;
662 difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
663 __n -= __dn;
664 __storage_type __m = std::__middle_mask<__storage_type>(__clz_f - __dn, __first.__ctz_);
665 __storage_type __b = *__first.__seg_ & __m;
666 unsigned __clz_r = __bits_per_word - __result.__ctz_;
667 __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
668 __m = std::__middle_mask<__storage_type>(__clz_r - __ddn, __result.__ctz_);
669 *__result.__seg_ &= ~__m;
670 if (__result.__ctz_ > __first.__ctz_)
671 *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
672 else
673 *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
674 __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
675 __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
676 __dn -= __ddn;
677 if (__dn > 0) {
678 __m = std::__trailing_mask<__storage_type>(__bits_per_word - __dn);
679 *__result.__seg_ &= ~__m;
680 *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
681 __result.__ctz_ = static_cast<unsigned>(__dn);
682 }
683 ++__first.__seg_;
684 // __first.__ctz_ = 0;
685 }
686 // __first.__ctz_ == 0;
687 // do middle words
688 unsigned __clz_r = __bits_per_word - __result.__ctz_;
689 __storage_type __m = std::__leading_mask<__storage_type>(__result.__ctz_);
690 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) {
691 __storage_type __b = *__first.__seg_;
692 *__result.__seg_ &= ~__m;
693 *__result.__seg_ |= __b << __result.__ctz_;
694 ++__result.__seg_;
695 *__result.__seg_ &= __m;
696 *__result.__seg_ |= __b >> __clz_r;
697 }
698 // do last word
699 if (__n > 0) {
700 __m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
701 __storage_type __b = *__first.__seg_ & __m;
702 __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r));
703 __m = std::__middle_mask<__storage_type>(__clz_r - __dn, __result.__ctz_);
704 *__result.__seg_ &= ~__m;
705 *__result.__seg_ |= __b << __result.__ctz_;
706 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
707 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
708 __n -= __dn;
709 if (__n > 0) {
710 __m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
711 *__result.__seg_ &= ~__m;
712 *__result.__seg_ |= __b >> __dn;
713 __result.__ctz_ = static_cast<unsigned>(__n);
714 }
715 }
716 }
717 return __result;
718 }
719
720 _LIBCPP_HIDE_FROM_ABI
721 _LIBCPP_CONSTEXPR_SINCE_CXX20 static pair<__bit_iterator<_Cp, _IsConst>, __bit_iterator<_Cp, false> >
722 operator()(__bit_iterator<_Cp, _IsConst> __first,
723 __bit_iterator<_Cp, _IsConst> __last,
724 __bit_iterator<_Cp, false> __result) {
725 if (__first.__ctz_ == __result.__ctz_)
726 return std::make_pair(__last, __aligned_impl(__first, __last, __result));
727 return std::make_pair(__last, __unaligned_impl(__first, __last, __result));
728 }
540729};
541730
542731_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__charconv/from_chars_integral.h+1-1
......@@ -18,8 +18,8 @@
1818#include <__memory/addressof.h>
1919#include <__system_error/errc.h>
2020#include <__type_traits/enable_if.h>
21#include <__type_traits/integral_constant.h>
2221#include <__type_traits/is_integral.h>
22#include <__type_traits/is_signed.h>
2323#include <__type_traits/is_unsigned.h>
2424#include <__type_traits/make_unsigned.h>
2525#include <limits>
lib/libcxx/include/__charconv/from_chars_result.h+1-1
......@@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121
2222#if _LIBCPP_STD_VER >= 17
2323
24struct _LIBCPP_EXPORTED_FROM_ABI from_chars_result {
24struct from_chars_result {
2525 const char* ptr;
2626 errc ec;
2727# if _LIBCPP_STD_VER >= 20
lib/libcxx/include/__charconv/to_chars_integral.h+1
......@@ -24,6 +24,7 @@
2424#include <__type_traits/integral_constant.h>
2525#include <__type_traits/is_integral.h>
2626#include <__type_traits/is_same.h>
27#include <__type_traits/is_signed.h>
2728#include <__type_traits/make_32_64_or_128_bit.h>
2829#include <__type_traits/make_unsigned.h>
2930#include <__utility/unreachable.h>
lib/libcxx/include/__charconv/to_chars_result.h+1-1
......@@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121
2222#if _LIBCPP_STD_VER >= 17
2323
24struct _LIBCPP_EXPORTED_FROM_ABI to_chars_result {
24struct to_chars_result {
2525 char* ptr;
2626 errc ec;
2727# if _LIBCPP_STD_VER >= 20
lib/libcxx/include/__charconv/traits.h+3-24
......@@ -113,31 +113,10 @@ struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__u
113113};
114114# endif
115115
116template <typename _Tp>
117inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
118__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r) {
119 auto __c = __a * __b;
120 __r = __c;
121 return __c > numeric_limits<unsigned char>::max();
122}
123
124template <typename _Tp>
125inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
126__mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r) {
127 auto __c = __a * __b;
128 __r = __c;
129 return __c > numeric_limits<unsigned short>::max();
130}
131
132template <typename _Tp>
133inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool __mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) {
134 static_assert(is_unsigned<_Tp>::value, "");
135 return __builtin_mul_overflow(__a, __b, std::addressof(__r));
136}
137
138116template <typename _Tp, typename _Up>
139inline _LIBCPP_HIDE_FROM_ABI bool _LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r) {
140 return __itoa::__mul_overflowed(__a, static_cast<_Tp>(__b), __r);
117_LIBCPP_HIDE_FROM_ABI bool _LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r) {
118 static_assert(is_unsigned<_Tp>::value);
119 return __builtin_mul_overflow(__a, static_cast<_Tp>(__b), std::addressof(__r));
141120}
142121
143122template <typename _Tp>
lib/libcxx/include/__chrono/day.h+11
......@@ -13,6 +13,8 @@
1313#include <__chrono/duration.h>
1414#include <__compare/ordering.h>
1515#include <__config>
16#include <__cstddef/size_t.h>
17#include <__functional/hash.h>
1618
1719#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1820# pragma GCC system_header
......@@ -92,6 +94,15 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator-=(const days& __dd) no
9294
9395} // namespace chrono
9496
97# if _LIBCPP_STD_VER >= 26
98
99template <>
100struct hash<chrono::day> {
101 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::day& __d) noexcept { return static_cast<unsigned>(__d); }
102};
103
104# endif // _LIBCPP_STD_VER >= 26
105
95106_LIBCPP_END_NAMESPACE_STD
96107
97108#endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/__chrono/duration.h+58-33
......@@ -13,6 +13,8 @@
1313#include <__compare/ordering.h>
1414#include <__compare/three_way_comparable.h>
1515#include <__config>
16#include <__cstddef/size_t.h>
17#include <__functional/hash.h>
1618#include <__type_traits/common_type.h>
1719#include <__type_traits/enable_if.h>
1820#include <__type_traits/is_convertible.h>
......@@ -102,7 +104,8 @@ struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> {
102104};
103105
104106template <class _ToDuration, class _Rep, class _Period, __enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
105inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration duration_cast(const duration<_Rep, _Period>& __fd) {
107[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration
108duration_cast(const duration<_Rep, _Period>& __fd) {
106109 return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd);
107110}
108111
......@@ -117,14 +120,18 @@ inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>:
117120template <class _Rep>
118121struct duration_values {
119122public:
120 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT { return _Rep(0); }
121 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT { return numeric_limits<_Rep>::max(); }
122 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT { return numeric_limits<_Rep>::lowest(); }
123 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT { return _Rep(0); }
124 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT {
125 return numeric_limits<_Rep>::max();
126 }
127 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {
128 return numeric_limits<_Rep>::lowest();
129 }
123130};
124131
125132#if _LIBCPP_STD_VER >= 17
126133template <class _ToDuration, class _Rep, class _Period, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
127inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration floor(const duration<_Rep, _Period>& __d) {
134[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration floor(const duration<_Rep, _Period>& __d) {
128135 _ToDuration __t = chrono::duration_cast<_ToDuration>(__d);
129136 if (__t > __d)
130137 __t = __t - _ToDuration{1};
......@@ -132,7 +139,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration floor(const duration<
132139}
133140
134141template <class _ToDuration, class _Rep, class _Period, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
135inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration ceil(const duration<_Rep, _Period>& __d) {
142[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration ceil(const duration<_Rep, _Period>& __d) {
136143 _ToDuration __t = chrono::duration_cast<_ToDuration>(__d);
137144 if (__t < __d)
138145 __t = __t + _ToDuration{1};
......@@ -140,7 +147,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration ceil(const duration<_
140147}
141148
142149template <class _ToDuration, class _Rep, class _Period, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
143inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration round(const duration<_Rep, _Period>& __d) {
150[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration round(const duration<_Rep, _Period>& __d) {
144151 _ToDuration __lower = chrono::floor<_ToDuration>(__d);
145152 _ToDuration __upper = __lower + _ToDuration{1};
146153 auto __lower_diff = __d - __lower;
......@@ -220,14 +227,14 @@ public:
220227
221228 // observer
222229
223 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR rep count() const { return __rep_; }
230 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR rep count() const { return __rep_; }
224231
225232 // arithmetic
226233
227 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<duration>::type operator+() const {
234 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<duration>::type operator+() const {
228235 return typename common_type<duration>::type(*this);
229236 }
230 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<duration>::type operator-() const {
237 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<duration>::type operator-() const {
231238 return typename common_type<duration>::type(-__rep_);
232239 }
233240 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator++() {
......@@ -269,13 +276,13 @@ public:
269276
270277 // special values
271278
272 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {
279 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {
273280 return duration(duration_values<rep>::zero());
274281 }
275 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {
282 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {
276283 return duration(duration_values<rep>::min());
277284 }
278 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {
285 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {
279286 return duration(duration_values<rep>::max());
280287 }
281288};
......@@ -389,7 +396,7 @@ operator<=>(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Perio
389396// Duration +
390397
391398template <class _Rep1, class _Period1, class _Rep2, class _Period2>
392inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
399[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
393400typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
394401operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
395402 typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
......@@ -399,7 +406,7 @@ operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2
399406// Duration -
400407
401408template <class _Rep1, class _Period1, class _Rep2, class _Period2>
402inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
409[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
403410typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
404411operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
405412 typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
......@@ -412,7 +419,8 @@ template <class _Rep1,
412419 class _Period,
413420 class _Rep2,
414421 __enable_if_t<is_convertible<const _Rep2&, typename common_type<_Rep1, _Rep2>::type>::value, int> = 0>
415inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
422[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
423_LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
416424operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) {
417425 typedef typename common_type<_Rep1, _Rep2>::type _Cr;
418426 typedef duration<_Cr, _Period> _Cd;
......@@ -423,7 +431,8 @@ template <class _Rep1,
423431 class _Period,
424432 class _Rep2,
425433 __enable_if_t<is_convertible<const _Rep1&, typename common_type<_Rep1, _Rep2>::type>::value, int> = 0>
426inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
434[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
435_LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
427436operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) {
428437 return __d * __s;
429438}
......@@ -436,7 +445,8 @@ template <class _Rep1,
436445 __enable_if_t<!__is_duration_v<_Rep2> &&
437446 is_convertible<const _Rep2&, typename common_type<_Rep1, _Rep2>::type>::value,
438447 int> = 0>
439inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
448[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
449_LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
440450operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) {
441451 typedef typename common_type<_Rep1, _Rep2>::type _Cr;
442452 typedef duration<_Cr, _Period> _Cd;
......@@ -444,7 +454,7 @@ operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) {
444454}
445455
446456template <class _Rep1, class _Period1, class _Rep2, class _Period2>
447inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<_Rep1, _Rep2>::type
457[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<_Rep1, _Rep2>::type
448458operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
449459 typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct;
450460 return _Ct(__lhs).count() / _Ct(__rhs).count();
......@@ -458,7 +468,8 @@ template <class _Rep1,
458468 __enable_if_t<!__is_duration_v<_Rep2> &&
459469 is_convertible<const _Rep2&, typename common_type<_Rep1, _Rep2>::type>::value,
460470 int> = 0>
461inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
471[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
472_LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
462473operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) {
463474 typedef typename common_type<_Rep1, _Rep2>::type _Cr;
464475 typedef duration<_Cr, _Period> _Cd;
......@@ -466,7 +477,7 @@ operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) {
466477}
467478
468479template <class _Rep1, class _Period1, class _Rep2, class _Period2>
469inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
480[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
470481typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
471482operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
472483 typedef typename common_type<_Rep1, _Rep2>::type _Cr;
......@@ -481,51 +492,53 @@ operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2
481492inline namespace literals {
482493inline namespace chrono_literals {
483494
484_LIBCPP_HIDE_FROM_ABI constexpr chrono::hours operator""h(unsigned long long __h) {
495[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours operator""h(unsigned long long __h) {
485496 return chrono::hours(static_cast<chrono::hours::rep>(__h));
486497}
487498
488_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, ratio<3600, 1>> operator""h(long double __h) {
499[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, ratio<3600, 1>>
500operator""h(long double __h) {
489501 return chrono::duration<long double, ratio<3600, 1>>(__h);
490502}
491503
492_LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes operator""min(unsigned long long __m) {
504[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes operator""min(unsigned long long __m) {
493505 return chrono::minutes(static_cast<chrono::minutes::rep>(__m));
494506}
495507
496_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, ratio<60, 1>> operator""min(long double __m) {
508[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, ratio<60, 1>>
509operator""min(long double __m) {
497510 return chrono::duration<long double, ratio<60, 1>>(__m);
498511}
499512
500_LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds operator""s(unsigned long long __s) {
513[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds operator""s(unsigned long long __s) {
501514 return chrono::seconds(static_cast<chrono::seconds::rep>(__s));
502515}
503516
504_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double> operator""s(long double __s) {
517[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double> operator""s(long double __s) {
505518 return chrono::duration<long double>(__s);
506519}
507520
508_LIBCPP_HIDE_FROM_ABI constexpr chrono::milliseconds operator""ms(unsigned long long __ms) {
521[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::milliseconds operator""ms(unsigned long long __ms) {
509522 return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(__ms));
510523}
511524
512_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, milli> operator""ms(long double __ms) {
525[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, milli> operator""ms(long double __ms) {
513526 return chrono::duration<long double, milli>(__ms);
514527}
515528
516_LIBCPP_HIDE_FROM_ABI constexpr chrono::microseconds operator""us(unsigned long long __us) {
529[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::microseconds operator""us(unsigned long long __us) {
517530 return chrono::microseconds(static_cast<chrono::microseconds::rep>(__us));
518531}
519532
520_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, micro> operator""us(long double __us) {
533[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, micro> operator""us(long double __us) {
521534 return chrono::duration<long double, micro>(__us);
522535}
523536
524_LIBCPP_HIDE_FROM_ABI constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) {
537[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) {
525538 return chrono::nanoseconds(static_cast<chrono::nanoseconds::rep>(__ns));
526539}
527540
528_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, nano> operator""ns(long double __ns) {
541[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, nano> operator""ns(long double __ns) {
529542 return chrono::duration<long double, nano>(__ns);
530543}
531544
......@@ -538,6 +551,18 @@ using namespace literals::chrono_literals;
538551
539552#endif // _LIBCPP_STD_VER >= 14
540553
554#if _LIBCPP_STD_VER >= 26
555
556template <class _Rep, class _Period>
557 requires __has_enabled_hash<_Rep>::value
558struct hash<chrono::duration<_Rep, _Period>> {
559 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::duration<_Rep, _Period>& __d) {
560 return hash<_Rep>{}(__d.count());
561 }
562};
563
564#endif // _LIBCPP_STD_VER >= 26
565
541566_LIBCPP_END_NAMESPACE_STD
542567
543568_LIBCPP_POP_MACROS
lib/libcxx/include/__chrono/file_clock.h+4-2
......@@ -60,16 +60,18 @@ struct _FilesystemClock {
6060
6161 _LIBCPP_EXPORTED_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false;
6262
63 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_EXPORTED_FROM_ABI static time_point now() noexcept;
63 [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI static time_point now() noexcept;
6464
6565# if _LIBCPP_STD_VER >= 20
6666 template <class _Duration>
67 [[nodiscard]]
6768 _LIBCPP_HIDE_FROM_ABI static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) {
6869 return chrono::sys_time<_Duration>(__t.time_since_epoch());
6970 }
7071
7172 template <class _Duration>
72 _LIBCPP_HIDE_FROM_ABI static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) {
73 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static chrono::file_time<_Duration>
74 from_sys(const chrono::sys_time<_Duration>& __t) {
7375 return chrono::file_time<_Duration>(__t.time_since_epoch());
7476 }
7577# endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/__chrono/is_clock.h created+72
......@@ -0,0 +1,72 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___CHRONO_IS_CLOCK_H
11#define _LIBCPP___CHRONO_IS_CLOCK_H
12
13#include <__config>
14
15#include <__chrono/duration.h>
16#include <__chrono/time_point.h>
17#include <__concepts/same_as.h>
18#include <__type_traits/integral_constant.h>
19#include <__type_traits/is_arithmetic.h>
20#include <__type_traits/is_class.h>
21#include <__type_traits/is_union.h>
22#include <ratio>
23
24#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25# pragma GCC system_header
26#endif
27
28#if _LIBCPP_STD_VER >= 20
29
30_LIBCPP_BEGIN_NAMESPACE_STD
31
32namespace chrono {
33
34// Helper to check that _Tp::time_point has the form time_point<_, typename _Tp::duration>.
35template <class _TimePoint, class _ClockType>
36inline constexpr bool __is_valid_clock_time_point_v = false;
37
38template <class _TimePointClock, class _ClockType>
39inline constexpr bool
40 __is_valid_clock_time_point_v<time_point<_TimePointClock, typename _ClockType::duration>, _ClockType> = true;
41
42// Check if a clock satisfies the Cpp17Clock requirements as defined in [time.clock.req]
43template <class _Tp>
44_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_clock_v = requires {
45 typename _Tp::rep;
46 requires is_arithmetic_v<typename _Tp::rep> || is_class_v<typename _Tp::rep> || is_union_v<typename _Tp::rep>;
47
48 typename _Tp::period;
49 requires __is_ratio_v<typename _Tp::period>;
50
51 typename _Tp::duration;
52 requires same_as<typename _Tp::duration, duration<typename _Tp::rep, typename _Tp::period>>;
53
54 typename _Tp::time_point;
55 requires __is_valid_clock_time_point_v<typename _Tp::time_point, _Tp>;
56
57 _Tp::is_steady;
58 requires same_as<decltype((_Tp::is_steady)), const bool&>;
59
60 _Tp::now();
61 requires same_as<decltype(_Tp::now()), typename _Tp::time_point>;
62};
63
64template <class _Tp>
65struct _LIBCPP_NO_SPECIALIZATIONS is_clock : bool_constant<is_clock_v<_Tp>> {};
66
67} // namespace chrono
68
69_LIBCPP_END_NAMESPACE_STD
70
71#endif // _LIBCPP_STD_VER
72#endif // _LIBCPP___CHRONO_IS_CLOCK_H
lib/libcxx/include/__chrono/leap_second.h+13
......@@ -22,6 +22,8 @@
2222# include <__compare/ordering.h>
2323# include <__compare/three_way_comparable.h>
2424# include <__config>
25# include <__cstddef/size_t.h>
26# include <__functional/hash.h>
2527# include <__utility/private_constructor_tag.h>
2628
2729# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -122,6 +124,17 @@ private:
122124
123125} // namespace chrono
124126
127# if _LIBCPP_STD_VER >= 26
128
129template <>
130struct hash<chrono::leap_second> {
131 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::leap_second& __lp) noexcept {
132 return std::__hash_combine(hash<chrono::sys_seconds>{}(__lp.date()), hash<chrono::seconds>{}(__lp.value()));
133 }
134};
135
136# endif // _LIBCPP_STD_VER >= 26
137
125138# endif // _LIBCPP_STD_VER >= 20
126139
127140_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__chrono/month.h+13
......@@ -13,6 +13,8 @@
1313#include <__chrono/duration.h>
1414#include <__compare/ordering.h>
1515#include <__config>
16#include <__cstddef/size_t.h>
17#include <__functional/hash.h>
1618
1719#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1820# pragma GCC system_header
......@@ -108,6 +110,17 @@ inline constexpr month December{12};
108110
109111} // namespace chrono
110112
113# if _LIBCPP_STD_VER >= 26
114
115template <>
116struct hash<chrono::month> {
117 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month& __m) noexcept {
118 return static_cast<unsigned>(__m);
119 }
120};
121
122# endif // _LIBCPP_STD_VER >= 26
123
111124_LIBCPP_END_NAMESPACE_STD
112125
113126#endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/__chrono/month_weekday.h+22
......@@ -13,6 +13,8 @@
1313#include <__chrono/month.h>
1414#include <__chrono/weekday.h>
1515#include <__config>
16#include <__cstddef/size_t.h>
17#include <__functional/hash.h>
1618
1719#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1820# pragma GCC system_header
......@@ -98,6 +100,26 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last operator/(const weekda
98100}
99101} // namespace chrono
100102
103# if _LIBCPP_STD_VER >= 26
104
105template <>
106struct hash<chrono::month_weekday> {
107 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_weekday& __mw) noexcept {
108 return std::__hash_combine(
109 hash<chrono::month>{}(__mw.month()), hash<chrono::weekday_indexed>{}(__mw.weekday_indexed()));
110 }
111};
112
113template <>
114struct hash<chrono::month_weekday_last> {
115 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_weekday_last& __mwl) noexcept {
116 return std::__hash_combine(
117 hash<chrono::month>{}(__mwl.month()), hash<chrono::weekday_last>{}(__mwl.weekday_last()));
118 }
119};
120
121# endif // _LIBCPP_STD_VER >= 26
122
101123_LIBCPP_END_NAMESPACE_STD
102124
103125#endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/__chrono/monthday.h+20
......@@ -15,6 +15,8 @@
1515#include <__chrono/month.h>
1616#include <__compare/ordering.h>
1717#include <__config>
18#include <__cstddef/size_t.h>
19#include <__functional/hash.h>
1820
1921#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2022# pragma GCC system_header
......@@ -126,6 +128,24 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(last_spec, int _
126128
127129} // namespace chrono
128130
131# if _LIBCPP_STD_VER >= 26
132
133template <>
134struct hash<chrono::month_day> {
135 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_day& __md) noexcept {
136 return std::__hash_combine(hash<chrono::month>{}(__md.month()), hash<chrono::day>{}(__md.day()));
137 }
138};
139
140template <>
141struct hash<chrono::month_day_last> {
142 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_day_last& __mdl) noexcept {
143 return hash<chrono::month>{}(__mdl.month());
144 }
145};
146
147# endif // _LIBCPP_STD_VER >= 26
148
129149_LIBCPP_END_NAMESPACE_STD
130150
131151#endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/__chrono/steady_clock.h+1-1
......@@ -31,7 +31,7 @@ public:
3131 typedef chrono::time_point<steady_clock, duration> time_point;
3232 static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = true;
3333
34 static time_point now() _NOEXCEPT;
34 [[__nodiscard__]] static time_point now() _NOEXCEPT;
3535};
3636#endif
3737
lib/libcxx/include/__chrono/system_clock.h+3-3
......@@ -31,9 +31,9 @@ public:
3131 typedef chrono::time_point<system_clock> time_point;
3232 static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false;
3333
34 static time_point now() _NOEXCEPT;
35 static time_t to_time_t(const time_point& __t) _NOEXCEPT;
36 static time_point from_time_t(time_t __t) _NOEXCEPT;
34 [[__nodiscard__]] static time_point now() _NOEXCEPT;
35 [[__nodiscard__]] static time_t to_time_t(const time_point& __t) _NOEXCEPT;
36 [[__nodiscard__]] static time_point from_time_t(time_t __t) _NOEXCEPT;
3737};
3838
3939#if _LIBCPP_STD_VER >= 20
lib/libcxx/include/__chrono/time_point.h+37-13
......@@ -14,6 +14,8 @@
1414#include <__compare/ordering.h>
1515#include <__compare/three_way_comparable.h>
1616#include <__config>
17#include <__cstddef/size_t.h>
18#include <__functional/hash.h>
1719#include <__type_traits/common_type.h>
1820#include <__type_traits/enable_if.h>
1921#include <__type_traits/is_convertible.h>
......@@ -54,7 +56,9 @@ public:
5456
5557 // observer
5658
57 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const { return __d_; }
59 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const {
60 return __d_;
61 }
5862
5963 // arithmetic
6064
......@@ -82,8 +86,12 @@ public:
8286
8387 // special values
8488
85 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT { return time_point(duration::min()); }
86 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT { return time_point(duration::max()); }
89 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {
90 return time_point(duration::min());
91 }
92 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {
93 return time_point(duration::max());
94 }
8795};
8896
8997} // namespace chrono
......@@ -95,30 +103,33 @@ struct common_type<chrono::time_point<_Clock, _Duration1>, chrono::time_point<_C
95103
96104namespace chrono {
97105
98template <class _ToDuration, class _Clock, class _Duration>
99inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, _ToDuration>
106template <class _ToDuration, class _Clock, class _Duration, __enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
107[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, _ToDuration>
100108time_point_cast(const time_point<_Clock, _Duration>& __t) {
101109 return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
102110}
103111
104112#if _LIBCPP_STD_VER >= 17
105113template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
106inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> floor(const time_point<_Clock, _Duration>& __t) {
114[[nodiscard]] inline
115 _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> floor(const time_point<_Clock, _Duration>& __t) {
107116 return time_point<_Clock, _ToDuration>{chrono::floor<_ToDuration>(__t.time_since_epoch())};
108117}
109118
110119template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
111inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> ceil(const time_point<_Clock, _Duration>& __t) {
120[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration>
121ceil(const time_point<_Clock, _Duration>& __t) {
112122 return time_point<_Clock, _ToDuration>{chrono::ceil<_ToDuration>(__t.time_since_epoch())};
113123}
114124
115125template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
116inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> round(const time_point<_Clock, _Duration>& __t) {
126[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration>
127round(const time_point<_Clock, _Duration>& __t) {
117128 return time_point<_Clock, _ToDuration>{chrono::round<_ToDuration>(__t.time_since_epoch())};
118129}
119130
120131template <class _Rep, class _Period, enable_if_t<numeric_limits<_Rep>::is_signed, int> = 0>
121inline _LIBCPP_HIDE_FROM_ABI constexpr duration<_Rep, _Period> abs(duration<_Rep, _Period> __d) {
132[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr duration<_Rep, _Period> abs(duration<_Rep, _Period> __d) {
122133 return __d >= __d.zero() ? +__d : -__d;
123134}
124135#endif // _LIBCPP_STD_VER >= 17
......@@ -188,7 +199,7 @@ operator<=>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock
188199// time_point operator+(time_point x, duration y);
189200
190201template <class _Clock, class _Duration1, class _Rep2, class _Period2>
191inline _LIBCPP_HIDE_FROM_ABI
202[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
192203_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
193204operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
194205 typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr;
......@@ -198,7 +209,7 @@ operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Pe
198209// time_point operator+(duration x, time_point y);
199210
200211template <class _Rep1, class _Period1, class _Clock, class _Duration2>
201inline _LIBCPP_HIDE_FROM_ABI
212[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
202213_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
203214operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
204215 return __rhs + __lhs;
......@@ -207,7 +218,7 @@ operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Dura
207218// time_point operator-(time_point x, duration y);
208219
209220template <class _Clock, class _Duration1, class _Rep2, class _Period2>
210inline _LIBCPP_HIDE_FROM_ABI
221[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
211222_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
212223operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
213224 typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret;
......@@ -217,13 +228,26 @@ operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Pe
217228// duration operator-(time_point x, time_point y);
218229
219230template <class _Clock, class _Duration1, class _Duration2>
220inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename common_type<_Duration1, _Duration2>::type
231[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
232typename common_type<_Duration1, _Duration2>::type
221233operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
222234 return __lhs.time_since_epoch() - __rhs.time_since_epoch();
223235}
224236
225237} // namespace chrono
226238
239#if _LIBCPP_STD_VER >= 26
240
241template <class _Clock, class _Duration>
242 requires __has_enabled_hash<_Duration>::value
243struct hash<chrono::time_point<_Clock, _Duration>> {
244 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::time_point<_Clock, _Duration>& __tp) {
245 return hash<_Duration>{}(__tp.time_since_epoch());
246 }
247};
248
249#endif // _LIBCPP_STD_VER >= 26
250
227251_LIBCPP_END_NAMESPACE_STD
228252
229253_LIBCPP_POP_MACROS
lib/libcxx/include/__chrono/weekday.h+25
......@@ -15,6 +15,8 @@
1515#include <__chrono/system_clock.h>
1616#include <__chrono/time_point.h>
1717#include <__config>
18#include <__cstddef/size_t.h>
19#include <__functional/hash.h>
1820
1921#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2022# pragma GCC system_header
......@@ -160,6 +162,29 @@ inline constexpr weekday Saturday{6};
160162
161163} // namespace chrono
162164
165# if _LIBCPP_STD_VER >= 26
166
167template <>
168struct hash<chrono::weekday> {
169 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday& __w) noexcept { return __w.c_encoding(); }
170};
171
172template <>
173struct hash<chrono::weekday_indexed> {
174 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday_indexed& __wi) noexcept {
175 return std::__hash_combine(hash<chrono::weekday>{}(__wi.weekday()), __wi.index());
176 }
177};
178
179template <>
180struct hash<chrono::weekday_last> {
181 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday_last& __wl) noexcept {
182 return hash<chrono::weekday>{}(__wl.weekday());
183 }
184};
185
186# endif // _LIBCPP_STD_VER >= 26
187
163188_LIBCPP_END_NAMESPACE_STD
164189
165190#endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/__chrono/year.h+11
......@@ -13,6 +13,8 @@
1313#include <__chrono/duration.h>
1414#include <__compare/ordering.h>
1515#include <__config>
16#include <__cstddef/size_t.h>
17#include <__functional/hash.h>
1618#include <limits>
1719
1820#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -109,6 +111,15 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept {
109111
110112} // namespace chrono
111113
114# if _LIBCPP_STD_VER >= 26
115
116template <>
117struct hash<chrono::year> {
118 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year& __y) noexcept { return static_cast<int>(__y); }
119};
120
121# endif // _LIBCPP_STD_VER >= 26
122
112123_LIBCPP_END_NAMESPACE_STD
113124
114125#endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/__chrono/year_month.h+13
......@@ -15,6 +15,8 @@
1515#include <__chrono/year.h>
1616#include <__compare/ordering.h>
1717#include <__config>
18#include <__cstddef/size_t.h>
19#include <__functional/hash.h>
1820
1921#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2022# pragma GCC system_header
......@@ -116,6 +118,17 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator-=(const
116118
117119} // namespace chrono
118120
121# if _LIBCPP_STD_VER >= 26
122
123template <>
124struct hash<chrono::year_month> {
125 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month& __ym) noexcept {
126 return std::__hash_combine(hash<chrono::year>{}(__ym.year()), hash<chrono::month>{}(__ym.month()));
127 }
128};
129
130# endif // _LIBCPP_STD_VER >= 26
131
119132_LIBCPP_END_NAMESPACE_STD
120133
121134#endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/__chrono/year_month_day.h+23
......@@ -21,6 +21,8 @@
2121#include <__chrono/year_month.h>
2222#include <__compare/ordering.h>
2323#include <__config>
24#include <__cstddef/size_t.h>
25#include <__functional/hash.h>
2426#include <limits>
2527
2628#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -330,6 +332,27 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr bool year_month_day::ok() const noexcept
330332
331333} // namespace chrono
332334
335# if _LIBCPP_STD_VER >= 26
336
337template <>
338struct hash<chrono::year_month_day> {
339 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_day& __ymd) noexcept {
340 return std::__hash_combine(
341 hash<chrono::year>{}(__ymd.year()),
342 std::__hash_combine(hash<chrono::month>{}(__ymd.month()), hash<chrono::day>{}(__ymd.day())));
343 }
344};
345
346template <>
347struct hash<chrono::year_month_day_last> {
348 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_day_last& __ymdl) noexcept {
349 return std::__hash_combine(
350 hash<chrono::year>{}(__ymdl.year()), hash<chrono::month_day_last>{}(__ymdl.month_day_last()));
351 }
352};
353
354# endif // _LIBCPP_STD_VER >= 26
355
333356_LIBCPP_END_NAMESPACE_STD
334357
335358#endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/__chrono/year_month_weekday.h+26
......@@ -22,6 +22,8 @@
2222#include <__chrono/year_month.h>
2323#include <__chrono/year_month_day.h>
2424#include <__config>
25#include <__cstddef/size_t.h>
26#include <__functional/hash.h>
2527
2628#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2729# pragma GCC system_header
......@@ -280,6 +282,30 @@ year_month_weekday_last::operator-=(const years& __dy) noexcept {
280282
281283} // namespace chrono
282284
285# if _LIBCPP_STD_VER >= 26
286
287template <>
288struct hash<chrono::year_month_weekday> {
289 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_weekday& __ymw) noexcept {
290 return std::__hash_combine(
291 hash<chrono::year>{}(__ymw.year()),
292 std::__hash_combine(
293 hash<chrono::month>{}(__ymw.month()), hash<chrono::weekday_indexed>{}(__ymw.weekday_indexed())));
294 }
295};
296
297template <>
298struct hash<chrono::year_month_weekday_last> {
299 _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_weekday_last& __ymwl) noexcept {
300 return std::__hash_combine(
301 hash<chrono::year>{}(__ymwl.year()),
302 std::__hash_combine(
303 hash<chrono::month>{}(__ymwl.month()), hash<chrono::weekday_last>{}(__ymwl.weekday_last())));
304 }
305};
306
307# endif // _LIBCPP_STD_VER >= 26
308
283309_LIBCPP_END_NAMESPACE_STD
284310
285311#endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/__chrono/zoned_time.h+16
......@@ -24,6 +24,8 @@
2424# include <__chrono/tzdb_list.h>
2525# include <__concepts/constructible.h>
2626# include <__config>
27# include <__cstddef/size_t.h>
28# include <__functional/hash.h>
2729# include <__type_traits/common_type.h>
2830# include <__type_traits/conditional.h>
2931# include <__type_traits/remove_cvref.h>
......@@ -216,6 +218,20 @@ operator==(const zoned_time<_Duration1, _TimeZonePtr>& __lhs, const zoned_time<_
216218
217219} // namespace chrono
218220
221# if _LIBCPP_STD_VER >= 26
222
223template <class _Duration, class _TimeZonePtr>
224 requires __has_enabled_hash<_Duration>::value && __has_enabled_hash<_TimeZonePtr>::value
225struct hash<chrono::zoned_time<_Duration, _TimeZonePtr>> {
226 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static size_t
227 operator()(const chrono::zoned_time<_Duration, _TimeZonePtr>& __zt) {
228 return std::__hash_combine(
229 hash<chrono::sys_time<_Duration>>{}(__zt.get_sys_time()), hash<_TimeZonePtr>{}(__zt.get_time_zone()));
230 }
231};
232
233# endif // _LIBCPP_STD_VER >= 26
234
219235# endif // _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM &&
220236 // _LIBCPP_HAS_LOCALIZATION
221237
lib/libcxx/include/__compare/is_eq.h+6-6
......@@ -20,12 +20,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2020
2121#if _LIBCPP_STD_VER >= 20
2222
23_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; }
24_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; }
25_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; }
26_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; }
27_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; }
28_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; }
23[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; }
24[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; }
25[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; }
26[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; }
27[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; }
28[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; }
2929
3030#endif // _LIBCPP_STD_VER >= 20
3131
lib/libcxx/include/__compare/strong_order.h+12-30
......@@ -13,7 +13,6 @@
1313#include <__compare/compare_three_way.h>
1414#include <__compare/ordering.h>
1515#include <__config>
16#include <__math/exponential_functions.h>
1716#include <__math/traits.h>
1817#include <__type_traits/conditional.h>
1918#include <__type_traits/decay.h>
......@@ -53,38 +52,21 @@ struct __fn {
5352 template <class _Tp, class _Up, class _Dp = decay_t<_Tp>>
5453 requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp>
5554 _LIBCPP_HIDE_FROM_ABI static constexpr strong_ordering __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept {
56 if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int32_t)) {
57 int32_t __rx = std::bit_cast<int32_t>(__t);
58 int32_t __ry = std::bit_cast<int32_t>(__u);
59 __rx = (__rx < 0) ? (numeric_limits<int32_t>::min() - __rx - 1) : __rx;
60 __ry = (__ry < 0) ? (numeric_limits<int32_t>::min() - __ry - 1) : __ry;
61 return (__rx <=> __ry);
62 } else if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int64_t)) {
63 int64_t __rx = std::bit_cast<int64_t>(__t);
64 int64_t __ry = std::bit_cast<int64_t>(__u);
65 __rx = (__rx < 0) ? (numeric_limits<int64_t>::min() - __rx - 1) : __rx;
66 __ry = (__ry < 0) ? (numeric_limits<int64_t>::min() - __ry - 1) : __ry;
55 if constexpr (numeric_limits<_Dp>::is_iec559 &&
56 (sizeof(_Dp) == sizeof(int32_t) || sizeof(_Dp) == sizeof(int64_t))) {
57 using _IntT = conditional_t<sizeof(_Dp) == sizeof(int32_t), int32_t, int64_t>;
58 _IntT __rx = std::bit_cast<_IntT>(__t);
59 _IntT __ry = std::bit_cast<_IntT>(__u);
60 __rx = (__rx < 0) ? (numeric_limits<_IntT>::min() - __rx - 1) : __rx;
61 __ry = (__ry < 0) ? (numeric_limits<_IntT>::min() - __ry - 1) : __ry;
6762 return (__rx <=> __ry);
6863 } else if (__t < __u) {
6964 return strong_ordering::less;
7065 } else if (__t > __u) {
7166 return strong_ordering::greater;
7267 } else if (__t == __u) {
73 if constexpr (numeric_limits<_Dp>::radix == 2) {
74 return __math::signbit(__u) <=> __math::signbit(__t);
75 } else {
76 // This is bullet 3 of the IEEE754 algorithm, relevant
77 // only for decimal floating-point;
78 // see https://stackoverflow.com/questions/69068075/
79 if (__t == 0 || __math::isinf(__t)) {
80 return __math::signbit(__u) <=> __math::signbit(__t);
81 } else {
82 int __texp, __uexp;
83 (void)__math::frexp(__t, &__texp);
84 (void)__math::frexp(__u, &__uexp);
85 return (__t < 0) ? (__texp <=> __uexp) : (__uexp <=> __texp);
86 }
87 }
68 static_assert(numeric_limits<_Dp>::radix == 2, "floating point type with a radix other than 2?");
69 return __math::signbit(__u) <=> __math::signbit(__t);
8870 } else {
8971 // They're unordered, so one of them must be a NAN.
9072 // The order is -QNAN, -SNAN, numbers, +SNAN, +QNAN.
......@@ -93,9 +75,9 @@ struct __fn {
9375 bool __t_is_negative = __math::signbit(__t);
9476 bool __u_is_negative = __math::signbit(__u);
9577 using _IntType =
96 conditional_t< sizeof(__t) == sizeof(int32_t),
97 int32_t,
98 conditional_t< sizeof(__t) == sizeof(int64_t), int64_t, void> >;
78 conditional_t<sizeof(__t) == sizeof(int32_t),
79 int32_t,
80 conditional_t<sizeof(__t) == sizeof(int64_t), int64_t, void>>;
9981 if constexpr (is_same_v<_IntType, void>) {
10082 static_assert(sizeof(_Dp) == 0, "std::strong_order is unimplemented for this floating-point type");
10183 } else if (__t_is_nan && __u_is_nan) {
lib/libcxx/include/__compare/three_way_comparable.h+2-2
......@@ -12,6 +12,7 @@
1212#include <__compare/common_comparison_category.h>
1313#include <__compare/ordering.h>
1414#include <__concepts/common_reference_with.h>
15#include <__concepts/comparison_common_type.h>
1516#include <__concepts/equality_comparable.h>
1617#include <__concepts/same_as.h>
1718#include <__concepts/totally_ordered.h>
......@@ -39,8 +40,7 @@ concept three_way_comparable =
3940
4041template <class _Tp, class _Up, class _Cat = partial_ordering>
4142concept three_way_comparable_with =
42 three_way_comparable<_Tp, _Cat> && three_way_comparable<_Up, _Cat> &&
43 common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> &&
43 three_way_comparable<_Tp, _Cat> && three_way_comparable<_Up, _Cat> && __comparison_common_type_with<_Tp, _Up> &&
4444 three_way_comparable<common_reference_t<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>>, _Cat> &&
4545 __weakly_equality_comparable_with<_Tp, _Up> && __partially_ordered_with<_Tp, _Up> &&
4646 requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
lib/libcxx/include/__concepts/comparison_common_type.h created+40
......@@ -0,0 +1,40 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___CONCEPTS_COMPARISON_COMMON_TYPE_H
10#define _LIBCPP___CONCEPTS_COMPARISON_COMMON_TYPE_H
11
12#include <__concepts/convertible_to.h>
13#include <__concepts/same_as.h>
14#include <__config>
15#include <__type_traits/common_reference.h>
16#include <__type_traits/remove_cvref.h>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19# pragma GCC system_header
20#endif
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24#if _LIBCPP_STD_VER >= 20
25
26template <class _Tp, class _Up, class _CommonRef = common_reference_t<const _Tp&, const _Up&>>
27concept __comparison_common_type_with_impl =
28 same_as<common_reference_t<const _Tp&, const _Up&>, common_reference_t<const _Up&, const _Tp&>> && requires {
29 requires convertible_to<const _Tp&, const _CommonRef&> || convertible_to<_Tp, const _CommonRef&>;
30 requires convertible_to<const _Up&, const _CommonRef&> || convertible_to<_Up, const _CommonRef&>;
31 };
32
33template <class _Tp, class _Up>
34concept __comparison_common_type_with = __comparison_common_type_with_impl<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
35
36#endif // _LIBCPP_STD_VER >= 20
37
38_LIBCPP_END_NAMESPACE_STD
39
40#endif // _LIBCPP___CONCEPTS_COMPARISON_COMMON_TYPE_H
lib/libcxx/include/__concepts/equality_comparable.h+2-1
......@@ -11,6 +11,7 @@
1111
1212#include <__concepts/boolean_testable.h>
1313#include <__concepts/common_reference_with.h>
14#include <__concepts/comparison_common_type.h>
1415#include <__config>
1516#include <__type_traits/common_reference.h>
1617#include <__type_traits/make_const_lvalue_ref.h>
......@@ -41,7 +42,7 @@ concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>;
4142template <class _Tp, class _Up>
4243concept equality_comparable_with =
4344 equality_comparable<_Tp> && equality_comparable<_Up> &&
44 common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> &&
45 __comparison_common_type_with<_Tp, _Up> &&
4546 equality_comparable<
4647 common_reference_t<
4748 __make_const_lvalue_ref<_Tp>,
lib/libcxx/include/__condition_variable/condition_variable.h+1-1
......@@ -170,7 +170,7 @@ public:
170170 wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred);
171171
172172 typedef __libcpp_condvar_t* native_handle_type;
173 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }
173 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }
174174
175175private:
176176 void
lib/libcxx/include/__config+63-280
......@@ -14,6 +14,8 @@
1414#include <__configuration/abi.h>
1515#include <__configuration/availability.h>
1616#include <__configuration/compiler.h>
17#include <__configuration/experimental.h>
18#include <__configuration/hardening.h>
1719#include <__configuration/language.h>
1820#include <__configuration/platform.h>
1921
......@@ -28,7 +30,7 @@
2830// _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM.
2931// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is
3032// defined to XXYYZZ.
31# define _LIBCPP_VERSION 210100
33# define _LIBCPP_VERSION 220104
3234
3335# define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
3436# define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)
......@@ -38,195 +40,6 @@
3840# define _LIBCPP_FREESTANDING
3941# endif
4042
41// NOLINTNEXTLINE(libcpp-cpp-version-check)
42# if __cplusplus < 201103L
43# define _LIBCPP_CXX03_LANG
44# endif
45
46# if __has_feature(experimental_library)
47# ifndef _LIBCPP_ENABLE_EXPERIMENTAL
48# define _LIBCPP_ENABLE_EXPERIMENTAL
49# endif
50# endif
51
52// Incomplete features get their own specific disabling flags. This makes it
53// easier to grep for target specific flags once the feature is complete.
54# if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY)
55# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1
56# else
57# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0
58# endif
59
60# define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
61# define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
62# define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
63# define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
64
65// HARDENING {
66
67// TODO(LLVM 23): Remove this. We're making these an error to catch folks who might not have migrated.
68// Since hardening went through several changes (many of which impacted user-facing macros),
69// we're keeping these checks around for a bit longer than usual. Failure to properly configure
70// hardening results in checks being dropped silently, which is a pretty big deal.
71# if defined(_LIBCPP_ENABLE_ASSERTIONS)
72# error "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
73# endif
74# if defined(_LIBCPP_ENABLE_HARDENED_MODE)
75# error "_LIBCPP_ENABLE_HARDENED_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
76# endif
77# if defined(_LIBCPP_ENABLE_SAFE_MODE)
78# error "_LIBCPP_ENABLE_SAFE_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
79# endif
80# if defined(_LIBCPP_ENABLE_DEBUG_MODE)
81# error "_LIBCPP_ENABLE_DEBUG_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
82# endif
83
84// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values:
85//
86// - `_LIBCPP_HARDENING_MODE_NONE`;
87// - `_LIBCPP_HARDENING_MODE_FAST`;
88// - `_LIBCPP_HARDENING_MODE_EXTENSIVE`;
89// - `_LIBCPP_HARDENING_MODE_DEBUG`.
90//
91// These values have the following effects:
92//
93// - `_LIBCPP_HARDENING_MODE_NONE` -- sets the hardening mode to "none" which disables all runtime hardening checks;
94//
95// - `_LIBCPP_HARDENING_MODE_FAST` -- sets that hardening mode to "fast". The fast mode enables security-critical checks
96// that can be done with relatively little runtime overhead in constant time;
97//
98// - `_LIBCPP_HARDENING_MODE_EXTENSIVE` -- sets the hardening mode to "extensive". The extensive mode is a superset of
99// the fast mode that additionally enables checks that are relatively cheap and prevent common types of logic errors
100// but are not necessarily security-critical;
101//
102// - `_LIBCPP_HARDENING_MODE_DEBUG` -- sets the hardening mode to "debug". The debug mode is a superset of the extensive
103// mode and enables all checks available in the library, including internal assertions. Checks that are part of the
104// debug mode can be very expensive and thus the debug mode is intended to be used for testing, not in production.
105
106// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These
107// macros are only for internal use -- users should only pick one of the high-level hardening modes described above.
108//
109// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and
110// a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid:
111// - the sentinel is reachable from the begin iterator;
112// - TODO(hardening): both iterators refer to the same container.
113//
114// - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through
115// the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access
116// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like
117// `optional` and `function` are considered one-element containers for the purposes of this check.
118//
119// - `_LIBCPP_ASSERT_NON_NULL` -- checks that the pointer being dereferenced is not null. On most modern platforms zero
120// address does not refer to an actual location in memory, so a null pointer dereference would not compromize the
121// memory security of a program (however, it is still undefined behavior that can result in strange errors due to
122// compiler optimizations).
123//
124// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the
125// given ranges do not overlap.
126//
127// - `_LIBCPP_ASSERT_VALID_DEALLOCATION` -- checks that an attempt to deallocate memory is valid (e.g. the given object
128// was allocated by the given allocator). Violating this category typically results in a memory leak.
129//
130// - `_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL` -- checks that a call to an external API doesn't fail in
131// an unexpected manner. This includes triggering documented cases of undefined behavior in an external library (like
132// attempting to unlock an unlocked mutex in pthreads). Any API external to the library falls under this category
133// (from system calls to compiler intrinsics). We generally don't expect these failures to compromize memory safety or
134// otherwise create an immediate security issue.
135//
136// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure
137// the containers have compatible allocators.
138//
139// - `_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN` -- checks that the given argument is within the domain of valid arguments
140// for the function. Violating this typically produces an incorrect result (e.g. the clamp algorithm returns the
141// original value without clamping it due to incorrect functors) or puts an object into an invalid state (e.g.
142// a string view where only a subset of elements is possible to access). This category is for assertions violating
143// which doesn't cause any immediate issues in the library -- whatever the consequences are, they will happen in the
144// user code.
145//
146// - `_LIBCPP_ASSERT_PEDANTIC` -- checks prerequisites which are imposed by the Standard, but violating which happens to
147// be benign in our implementation.
148//
149// - `_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT` -- checks that the given argument satisfies the semantic requirements imposed
150// by the Standard. Typically, there is no simple way to completely prove that a semantic requirement is satisfied;
151// thus, this would often be a heuristic check and it might be quite expensive.
152//
153// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on
154// user input.
155//
156// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet.
157
158// clang-format off
159# define _LIBCPP_HARDENING_MODE_NONE (1 << 1)
160# define _LIBCPP_HARDENING_MODE_FAST (1 << 2)
161# define _LIBCPP_HARDENING_MODE_EXTENSIVE (1 << 4) // Deliberately not ordered.
162# define _LIBCPP_HARDENING_MODE_DEBUG (1 << 3)
163// clang-format on
164
165# ifndef _LIBCPP_HARDENING_MODE
166
167# ifndef _LIBCPP_HARDENING_MODE_DEFAULT
168# error _LIBCPP_HARDENING_MODE_DEFAULT is not defined. This definition should be set at configuration time in the \
169`__config_site` header, please make sure your installation of libc++ is not broken.
170# endif
171
172# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT
173# endif
174
175# if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_NONE && \
176 _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_FAST && \
177 _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_EXTENSIVE && \
178 _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
179# error _LIBCPP_HARDENING_MODE must be set to one of the following values: \
180_LIBCPP_HARDENING_MODE_NONE, \
181_LIBCPP_HARDENING_MODE_FAST, \
182_LIBCPP_HARDENING_MODE_EXTENSIVE, \
183_LIBCPP_HARDENING_MODE_DEBUG
184# endif
185
186// Hardening assertion semantics generally mirror the evaluation semantics of C++26 Contracts:
187// - `ignore` evaluates the assertion but doesn't do anything if it fails (note that it differs from the Contracts
188// `ignore` semantic which wouldn't evaluate the assertion at all);
189// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution;
190// - `quick-enforce` terminates the program as fast as possible (via trapping);
191// - `enforce` logs an error and then terminates the program.
192//
193// Notes:
194// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant
195// to make adopting hardening easier but should not be used outside of this scenario;
196// - C++26 wording for Library Hardening precludes a conforming Hardened implementation from using the Contracts
197// `ignore` semantic when evaluating hardened preconditions in the Library. Libc++ allows using this semantic for
198// hardened preconditions, however, be aware that using `ignore` does not produce a conforming "Hardened"
199// implementation, unlike the other semantics above.
200// clang-format off
201# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 1)
202# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 2)
203# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 3)
204# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 4)
205// clang-format on
206
207// Allow users to define an arbitrary assertion semantic; otherwise, use the default mapping from modes to semantics.
208// The default is for production-capable modes to use `quick-enforce` (i.e., trap) and for the `debug` mode to use
209// `enforce` (i.e., log and abort).
210# ifndef _LIBCPP_ASSERTION_SEMANTIC
211
212# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
213# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
214# else
215# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
216# endif
217
218# else
219# if !_LIBCPP_HAS_EXPERIMENTAL_LIBRARY
220# error "Assertion semantics are an experimental feature."
221# endif
222# if defined(_LIBCPP_CXX03_LANG)
223# error "Assertion semantics are not available in the C++03 mode."
224# endif
225
226# endif // _LIBCPP_ASSERTION_SEMANTIC
227
228// } HARDENING
229
23043# define _LIBCPP_TOSTRING2(x) #x
23144# define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
23245
......@@ -320,13 +133,6 @@ _LIBCPP_HARDENING_MODE_DEBUG
320133// When this option is used, the token passed to `std::random_device`'s
321134// constructor *must* be "/dev/urandom" -- anything else is an error.
322135//
323// _LIBCPP_USING_NACL_RANDOM
324// NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access,
325// including accesses to the special files under `/dev`. This implementation
326// uses the NaCL syscall `nacl_secure_random_init()` to get entropy.
327// When this option is used, the token passed to `std::random_device`'s
328// constructor *must* be "/dev/urandom" -- anything else is an error.
329//
330136// _LIBCPP_USING_WIN32_RANDOM
331137// Use rand_s(), for use on Windows.
332138// When this option is used, the token passed to `std::random_device`'s
......@@ -338,8 +144,6 @@ _LIBCPP_HARDENING_MODE_DEBUG
338144# define _LIBCPP_USING_GETENTROPY
339145# elif defined(__Fuchsia__)
340146# define _LIBCPP_USING_FUCHSIA_CPRNG
341# elif defined(__native_client__)
342# define _LIBCPP_USING_NACL_RANDOM
343147# elif defined(_LIBCPP_WIN32API)
344148# define _LIBCPP_USING_WIN32_RANDOM
345149# else
......@@ -348,7 +152,7 @@ _LIBCPP_HARDENING_MODE_DEBUG
348152
349153# ifndef _LIBCPP_CXX03_LANG
350154
351# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp)
155# define _LIBCPP_ALIGNOF(...) alignof(__VA_ARGS__)
352156# define _ALIGNAS_TYPE(x) alignas(x)
353157# define _ALIGNAS(x) alignas(x)
354158# define _NOEXCEPT noexcept
......@@ -357,7 +161,7 @@ _LIBCPP_HARDENING_MODE_DEBUG
357161
358162# else
359163
360# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp)
164# define _LIBCPP_ALIGNOF(...) _Alignof(__VA_ARGS__)
361165# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
362166# define _ALIGNAS(x) __attribute__((__aligned__(x)))
363167# define nullptr __nullptr
......@@ -471,6 +275,12 @@ typedef __char32_t char32_t;
471275# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
472276# endif
473277
278// Macros to enter and leave a state where deprecation warnings are suppressed.
279# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH \
280 _LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated") \
281 _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations")
282# define _LIBCPP_SUPPRESS_DEPRECATED_POP _LIBCPP_DIAGNOSTIC_POP
283
474284# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
475285# define _LIBCPP_HARDENING_SIG f
476286# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_EXTENSIVE
......@@ -481,6 +291,16 @@ typedef __char32_t char32_t;
481291# define _LIBCPP_HARDENING_SIG n // "none"
482292# endif
483293
294# if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE
295# define _LIBCPP_ASSERTION_SEMANTIC_SIG o
296# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
297# define _LIBCPP_ASSERTION_SEMANTIC_SIG q
298# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
299# define _LIBCPP_ASSERTION_SEMANTIC_SIG e
300# else
301# define _LIBCPP_ASSERTION_SEMANTIC_SIG i // `ignore`
302# endif
303
484304# if !_LIBCPP_HAS_EXCEPTIONS
485305# define _LIBCPP_EXCEPTIONS_SIG n
486306# else
......@@ -488,7 +308,9 @@ typedef __char32_t char32_t;
488308# endif
489309
490310# define _LIBCPP_ODR_SIGNATURE \
491 _LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_EXCEPTIONS_SIG), _LIBCPP_VERSION)
311 _LIBCPP_CONCAT( \
312 _LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_ASSERTION_SEMANTIC_SIG), _LIBCPP_EXCEPTIONS_SIG), \
313 _LIBCPP_VERSION)
492314
493315// This macro marks a symbol as being hidden from libc++'s ABI. This is achieved
494316// on two levels:
......@@ -550,16 +372,6 @@ typedef __char32_t char32_t;
550372# endif
551373# define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
552374
553# ifdef _LIBCPP_BUILDING_LIBRARY
554# if _LIBCPP_ABI_VERSION > 1
555# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
556# else
557# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1
558# endif
559# else
560# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
561# endif
562
563375// Clang modules take a significant compile time hit when pushing and popping diagnostics.
564376// Since all the headers are marked as system headers unless _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER is defined, we can
565377// simply disable this pushing and popping when _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER isn't defined.
......@@ -676,27 +488,6 @@ typedef __char32_t char32_t;
676488# endif
677489# endif
678490
679// It is not yet possible to use aligned_alloc() on all Apple platforms since
680// 10.15 was the first version to ship an implementation of aligned_alloc().
681# if defined(__APPLE__)
682# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
683 __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \
684 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
685 __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
686 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \
687 __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000) || \
688 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000)
689# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 0
690# else
691# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 1
692# endif
693# elif defined(__ANDROID__) && __ANDROID_API__ < 28
694// Android only provides aligned_alloc when targeting API 28 or higher.
695# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 0
696# else
697# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 1
698# endif
699
700491# if defined(__APPLE__) || defined(__FreeBSD__)
701492# define _LIBCPP_WCTYPE_IS_MASK
702493# endif
......@@ -727,6 +518,15 @@ typedef __char32_t char32_t;
727518# define _LIBCPP_DEPRECATED_(m)
728519# endif
729520
521// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be
522// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that
523// allows suppression in system headers.
524# if defined(__DEPRECATED) && __DEPRECATED && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && 0
525# define _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS 1
526# else
527# define _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS 0
528# endif
529
730530# if !defined(_LIBCPP_CXX03_LANG)
731531# define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED
732532# else
......@@ -771,17 +571,6 @@ typedef __char32_t char32_t;
771571# define _LIBCPP_DEPRECATED_WITH_CHAR8_T
772572# endif
773573
774// Macros to enter and leave a state where deprecation warnings are suppressed.
775# if defined(_LIBCPP_COMPILER_CLANG_BASED) || defined(_LIBCPP_COMPILER_GCC)
776# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH \
777 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wdeprecated\"") \
778 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
779# define _LIBCPP_SUPPRESS_DEPRECATED_POP _Pragma("GCC diagnostic pop")
780# else
781# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH
782# define _LIBCPP_SUPPRESS_DEPRECATED_POP
783# endif
784
785574# if _LIBCPP_STD_VER <= 11
786575# define _LIBCPP_EXPLICIT_SINCE_CXX14
787576# else
......@@ -861,18 +650,10 @@ typedef __char32_t char32_t;
861650# endif // _LIBCPP_HAS_THREAD_API
862651# endif // _LIBCPP_HAS_THREADS
863652
864# if _LIBCPP_HAS_THREAD_API_PTHREAD
865# if defined(__ANDROID__) && __ANDROID_API__ >= 30
866# define _LIBCPP_HAS_COND_CLOCKWAIT 1
867# elif defined(_LIBCPP_GLIBC_PREREQ)
868# if _LIBCPP_GLIBC_PREREQ(2, 30)
869# define _LIBCPP_HAS_COND_CLOCKWAIT 1
870# else
871# define _LIBCPP_HAS_COND_CLOCKWAIT 0
872# endif
873# else
874# define _LIBCPP_HAS_COND_CLOCKWAIT 0
875# endif
653# if !_LIBCPP_HAS_THREAD_API_PTHREAD
654# define _LIBCPP_HAS_COND_CLOCKWAIT 0
655# elif (defined(__ANDROID__) && __ANDROID_API__ >= 30) || _LIBCPP_GLIBC_PREREQ(2, 30)
656# define _LIBCPP_HAS_COND_CLOCKWAIT 1
876657# else
877658# define _LIBCPP_HAS_COND_CLOCKWAIT 0
878659# endif
......@@ -951,8 +732,8 @@ typedef __char32_t char32_t;
951732# endif
952733# endif
953734
954# if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(__no_thread_safety_analysis__)
955# define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((__no_thread_safety_analysis__))
735# if __has_cpp_attribute(_Clang::__no_thread_safety_analysis__)
736# define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS [[_Clang::__no_thread_safety_analysis__]]
956737# else
957738# define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
958739# endif
......@@ -1038,12 +819,8 @@ typedef __char32_t char32_t;
1038819// the latter depends on internal GNU libc details that are not appropriate
1039820// to depend on here, so any declarations present when __cpp_char8_t is not
1040821// defined are ignored.
1041# if defined(_LIBCPP_GLIBC_PREREQ)
1042# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t)
1043# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
1044# else
1045# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
1046# endif
822# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t)
823# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
1047824# else
1048825# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
1049826# endif
......@@ -1067,8 +844,7 @@ typedef __char32_t char32_t;
1067844# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "")
1068845# endif
1069846
1070// TODO(LLVM 22): Remove the workaround
1071# if defined(__OBJC__) && (!defined(_LIBCPP_CLANG_VER) || _LIBCPP_CLANG_VER < 2001)
847# if defined(__OBJC__) && defined(_LIBCPP_APPLE_CLANG_VER)
1072848# define _LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS
1073849# endif
1074850
......@@ -1153,12 +929,33 @@ typedef __char32_t char32_t;
1153929# define _LIBCPP_DIAGNOSE_WARNING(...)
1154930# endif
1155931
932# if __has_attribute(__diagnose_if__) && !defined(_LIBCPP_APPLE_CLANG_VER) && \
933 (!defined(_LIBCPP_CLANG_VER) || _LIBCPP_CLANG_VER >= 2001)
934# define _LIBCPP_DIAGNOSE_IF(...) __attribute__((__diagnose_if__(__VA_ARGS__)))
935# else
936# define _LIBCPP_DIAGNOSE_IF(...)
937# endif
938
939# define _LIBCPP_DIAGNOSE_NULLPTR_IF(condition, condition_description) \
940 _LIBCPP_DIAGNOSE_IF( \
941 condition, \
942 "null passed to callee that requires a non-null argument" condition_description, \
943 "warning", \
944 "nonnull")
945
1156946# if __has_cpp_attribute(_Clang::__lifetimebound__)
1157947# define _LIBCPP_LIFETIMEBOUND [[_Clang::__lifetimebound__]]
1158948# else
1159949# define _LIBCPP_LIFETIMEBOUND
1160950# endif
1161951
952// This is to work around https://llvm.org/PR156809
953# ifndef _LIBCPP_CXX03_LANG
954# define _LIBCPP_CTOR_LIFETIMEBOUND _LIBCPP_LIFETIMEBOUND
955# else
956# define _LIBCPP_CTOR_LIFETIMEBOUND
957# endif
958
1162959# if __has_cpp_attribute(_Clang::__noescape__)
1163960# define _LIBCPP_NOESCAPE [[_Clang::__noescape__]]
1164961# else
......@@ -1172,12 +969,6 @@ typedef __char32_t char32_t;
1172969# define _LIBCPP_NO_SPECIALIZATIONS
1173970# endif
1174971
1175# if __has_cpp_attribute(_Clang::__standalone_debug__)
1176# define _LIBCPP_STANDALONE_DEBUG [[_Clang::__standalone_debug__]]
1177# else
1178# define _LIBCPP_STANDALONE_DEBUG
1179# endif
1180
1181972# if __has_cpp_attribute(_Clang::__preferred_name__)
1182973# define _LIBCPP_PREFERRED_NAME(x) [[_Clang::__preferred_name__(x)]]
1183974# else
......@@ -1257,14 +1048,6 @@ typedef __char32_t char32_t;
12571048# define _LIBCPP_DIAGNOSE_NULLPTR
12581049# endif
12591050
1260// TODO(LLVM 22): Remove this macro once LLVM19 support ends. __cpp_explicit_this_parameter has been set in LLVM20.
1261// Clang-18 has support for deducing this, but it does not set the FTM.
1262# if defined(__cpp_explicit_this_parameter) || (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1800)
1263# define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 1
1264# else
1265# define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 0
1266# endif
1267
12681051#endif // __cplusplus
12691052
12701053#endif // _LIBCPP___CONFIG
lib/libcxx/include/__configuration/abi.h+14-24
......@@ -61,19 +61,9 @@
6161// According to the Standard, `bitset::operator[] const` returns bool
6262# define _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
6363
64// In LLVM 20, we've changed to take these ABI breaks unconditionally. These flags only exist in case someone is running
65// into the static_asserts we added to catch the ABI break and don't care that it is one.
66// TODO(LLVM 22): Remove these flags
67# define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB
68# define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB
69# define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB
70# define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB
71
7264// These flags are documented in ABIGuarantees.rst
7365# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
74# define _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON
75# define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
76# define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
66# define _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
7767# define _LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI
7868# define _LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI
7969# define _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION
......@@ -84,25 +74,16 @@
8474# define _LIBCPP_ABI_NO_FILESYSTEM_INLINE_NAMESPACE
8575# define _LIBCPP_ABI_NO_ITERATOR_BASES
8676# define _LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT
77# define _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER
8778# define _LIBCPP_ABI_OPTIMIZED_FUNCTION
8879# define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
8980# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
9081# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY
9182# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW
9283# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
84# define _LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR
9385
9486#elif _LIBCPP_ABI_VERSION == 1
95# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
96// Enable compiling copies of now inline methods into the dylib to support
97// applications compiled against older libraries. This is unnecessary with
98// COFF dllexport semantics, since dllexport forces a non-inline definition
99// of inline functions to be emitted anyway. Our own non-inline copy would
100// conflict with the dllexport-emitted copy, so we disable it. For XCOFF,
101// the linker will take issue with the symbols in the shared object if the
102// weak inline methods get visibility (such as from -fvisibility-inlines-hidden),
103// so disable it.
104# define _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS
105# endif
10687// Feature macros for disabling pre ABI v1 features. All of these options
10788// are deprecated.
10889# if defined(__FreeBSD__)
......@@ -110,11 +91,20 @@
11091# endif
11192#endif
11293
94// TODO(LLVM 22): Remove this check
95#if defined(_LIBCPP_ABI_NO_ITERATOR_BASES) && !defined(_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER)
96# ifndef _LIBCPP_ONLY_NO_ITERATOR_BASES
97# error "You probably want to define _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER. This has been split out from" \
98 " _LIBCPP_ABI_NO_ITERATOR_BASES to allow only removing the second iterator member, since they aren't really related." \
99 "If you actually want this ABI configuration, please define _LIBCPP_ONLY_NO_ITERATOR_BASES instead."
100# endif
101#endif
102
113103// We had some bugs where we use [[no_unique_address]] together with construct_at,
114104// which causes UB as the call on construct_at could write to overlapping subobjects
115105//
116// https://github.com/llvm/llvm-project/issues/70506
117// https://github.com/llvm/llvm-project/issues/70494
106// https://llvm.org/PR70506
107// https://llvm.org/PR70494
118108//
119109// To fix the bug we had to change the ABI of some classes to remove [[no_unique_address]] under certain conditions.
120110// The macro below is used for all classes whose ABI have changed as part of fixing these bugs.
lib/libcxx/include/__configuration/availability.h+65-118
......@@ -17,62 +17,17 @@
1717# pragma GCC system_header
1818#endif
1919
20// Libc++ is shipped by various vendors. In particular, it is used as a system
21// library on macOS, iOS and other Apple platforms. In order for users to be
22// able to compile a binary that is intended to be deployed to an older version
23// of a platform, Clang provides availability attributes [1]. These attributes
24// can be placed on declarations and are used to describe the life cycle of a
25// symbol in the library.
26//
27// The main goal is to ensure a compile-time error if a symbol that hasn't been
28// introduced in a previously released library is used in a program that targets
29// that previously released library. Normally, this would be a load-time error
30// when one tries to launch the program against the older library.
31//
32// For example, the filesystem library was introduced in the dylib in LLVM 9.
33// On Apple platforms, this corresponds to macOS 10.15. If a user compiles on
34// a macOS 10.15 host but targets macOS 10.13 with their program, the compiler
35// would normally not complain (because the required declarations are in the
36// headers), but the dynamic loader would fail to find the symbols when actually
37// trying to launch the program on macOS 10.13. To turn this into a compile-time
38// issue instead, declarations are annotated with when they were introduced, and
39// the compiler can produce a diagnostic if the program references something that
40// isn't available on the deployment target.
41//
42// This mechanism is general in nature, and any vendor can add their markup to
43// the library (see below). Whenever a new feature is added that requires support
44// in the shared library, two macros are added below to allow marking the feature
45// as unavailable:
46// 1. A macro named `_LIBCPP_AVAILABILITY_HAS_<feature>` which must be defined
47// to `_LIBCPP_INTRODUCED_IN_<version>` for the appropriate LLVM version.
48// 2. A macro named `_LIBCPP_AVAILABILITY_<feature>`, which must be defined to
49// `_LIBCPP_INTRODUCED_IN_<version>_MARKUP` for the appropriate LLVM version.
50//
51// When vendors decide to ship the feature as part of their shared library, they
52// can update the `_LIBCPP_INTRODUCED_IN_<version>` macro (and the markup counterpart)
53// based on the platform version they shipped that version of LLVM in. The library
54// will then use this markup to provide an optimal user experience on these platforms.
55//
56// Furthermore, many features in the standard library have corresponding
57// feature-test macros. The `_LIBCPP_AVAILABILITY_HAS_<feature>` macros
58// are checked by the corresponding feature-test macros generated by
59// generate_feature_test_macro_components.py to ensure that the library
60// doesn't announce a feature as being implemented if it is unavailable on
61// the deployment target.
62//
63// Note that this mechanism is disabled by default in the "upstream" libc++.
64// Availability annotations are only meaningful when shipping libc++ inside
65// a platform (i.e. as a system library), and so vendors that want them should
66// turn those annotations on at CMake configuration time.
67//
68// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability
20// This file defines a framework that can be used by vendors to encode the version of an operating system that various
21// features of libc++ has been shipped in. This is primarily intended to allow safely deploying an executable built with
22// a new version of the library on a platform containing an older version of the built library.
23// Detailed documentation for this can be found at https://libcxx.llvm.org/VendorDocumentation.html#availability-markup
6924
7025// Availability markup is disabled when building the library, or when a non-Clang
7126// compiler is used because only Clang supports the necessary attributes.
7227//
7328// We also allow users to force-disable availability markup via the `_LIBCPP_DISABLE_AVAILABILITY`
7429// macro because that is the only way to work around a Clang bug related to availability
75// attributes: https://github.com/llvm/llvm-project/issues/134151.
30// attributes: https://llvm.org/PR134151.
7631// Once that bug has been fixed, we should remove the macro.
7732#if defined(_LIBCPP_BUILDING_LIBRARY) || defined(_LIBCXXABI_BUILDING_LIBRARY) || \
7833 !defined(_LIBCPP_COMPILER_CLANG_BASED) || defined(_LIBCPP_DISABLE_AVAILABILITY)
......@@ -84,6 +39,9 @@
8439// in all versions of the library are available.
8540#if !_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS
8641
42# define _LIBCPP_INTRODUCED_IN_LLVM_22 1
43# define _LIBCPP_INTRODUCED_IN_LLVM_22_ATTRIBUTE /* nothing */
44
8745# define _LIBCPP_INTRODUCED_IN_LLVM_21 1
8846# define _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE /* nothing */
8947
......@@ -108,32 +66,55 @@
10866# define _LIBCPP_INTRODUCED_IN_LLVM_12 1
10967# define _LIBCPP_INTRODUCED_IN_LLVM_12_ATTRIBUTE /* nothing */
11068
111# define _LIBCPP_INTRODUCED_IN_LLVM_11 1
112# define _LIBCPP_INTRODUCED_IN_LLVM_11_ATTRIBUTE /* nothing */
113
114# define _LIBCPP_INTRODUCED_IN_LLVM_9 1
115# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE /* nothing */
116# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_PUSH /* nothing */
117# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_POP /* nothing */
118
11969#elif defined(__APPLE__)
12070
12171// clang-format off
12272
73// LLVM 22
74// TODO: Fill this in
75# define _LIBCPP_INTRODUCED_IN_LLVM_22 0
76# define _LIBCPP_INTRODUCED_IN_LLVM_22_ATTRIBUTE __attribute__((unavailable))
77
12378// LLVM 21
12479// TODO: Fill this in
12580# define _LIBCPP_INTRODUCED_IN_LLVM_21 0
12681# define _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE __attribute__((unavailable))
12782
12883// LLVM 20
129// TODO: Fill this in
130# define _LIBCPP_INTRODUCED_IN_LLVM_20 0
131# define _LIBCPP_INTRODUCED_IN_LLVM_20_ATTRIBUTE __attribute__((unavailable))
84//
85// Note that versions for most Apple OSes were bumped forward and aligned in that release.
86# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 260000) || \
87 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 260000) || \
88 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 260000) || \
89 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 260000) || \
90 (defined(__ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__ < 100000)
91# define _LIBCPP_INTRODUCED_IN_LLVM_20 0
92# else
93# define _LIBCPP_INTRODUCED_IN_LLVM_20 1
94# endif
95# define _LIBCPP_INTRODUCED_IN_LLVM_20_ATTRIBUTE \
96 __attribute__((availability(macos, strict, introduced = 26.0))) \
97 __attribute__((availability(ios, strict, introduced = 26.0))) \
98 __attribute__((availability(tvos, strict, introduced = 26.0))) \
99 __attribute__((availability(watchos, strict, introduced = 26.0))) \
100 __attribute__((availability(bridgeos, strict, introduced = 10.0)))
132101
133102// LLVM 19
134// TODO: Fill this in
135# define _LIBCPP_INTRODUCED_IN_LLVM_19 0
136# define _LIBCPP_INTRODUCED_IN_LLVM_19_ATTRIBUTE __attribute__((unavailable))
103# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 150400) || \
104 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 180400) || \
105 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 180400) || \
106 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 110400) || \
107 (defined(__ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__ < 90400)
108# define _LIBCPP_INTRODUCED_IN_LLVM_19 0
109# else
110# define _LIBCPP_INTRODUCED_IN_LLVM_19 1
111# endif
112# define _LIBCPP_INTRODUCED_IN_LLVM_19_ATTRIBUTE \
113 __attribute__((availability(macos, strict, introduced = 15.4))) \
114 __attribute__((availability(ios, strict, introduced = 18.4))) \
115 __attribute__((availability(tvos, strict, introduced = 18.4))) \
116 __attribute__((availability(watchos, strict, introduced = 11.4))) \
117 __attribute__((availability(bridgeos, strict, introduced = 9.4)))
137118
138119// LLVM 18
139120# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 150000) || \
......@@ -215,47 +196,13 @@
215196 __attribute__((availability(bridgeos, strict, introduced = 6.0))) \
216197 __attribute__((availability(driverkit, strict, introduced = 21.3)))
217198
218// LLVM 11
219# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) || \
220 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \
221 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 140000) || \
222 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 70000)
223# define _LIBCPP_INTRODUCED_IN_LLVM_11 0
224# else
225# define _LIBCPP_INTRODUCED_IN_LLVM_11 1
199# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) || \
200 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 150000) || \
201 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 150000) || \
202 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 80000) || \
203 (defined(__ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__ < 200000)
204# warning "The selected platform is no longer supported by libc++."
226205# endif
227# define _LIBCPP_INTRODUCED_IN_LLVM_11_ATTRIBUTE \
228 __attribute__((availability(macos, strict, introduced = 11.0))) \
229 __attribute__((availability(ios, strict, introduced = 14.0))) \
230 __attribute__((availability(tvos, strict, introduced = 14.0))) \
231 __attribute__((availability(watchos, strict, introduced = 7.0)))
232
233// LLVM 9
234# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \
235 (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
236 (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) || \
237 (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000)
238# define _LIBCPP_INTRODUCED_IN_LLVM_9 0
239# else
240# define _LIBCPP_INTRODUCED_IN_LLVM_9 1
241# endif
242# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE \
243 __attribute__((availability(macos, strict, introduced = 10.15))) \
244 __attribute__((availability(ios, strict, introduced = 13.0))) \
245 __attribute__((availability(tvos, strict, introduced = 13.0))) \
246 __attribute__((availability(watchos, strict, introduced = 6.0)))
247# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_PUSH \
248 _Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \
249 _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \
250 _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \
251 _Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))")
252# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_POP \
253 _Pragma("clang attribute pop") \
254 _Pragma("clang attribute pop") \
255 _Pragma("clang attribute pop") \
256 _Pragma("clang attribute pop")
257
258// clang-format on
259206
260207#else
261208
......@@ -266,19 +213,12 @@
266213
267214#endif
268215
269// These macros control the availability of all parts of <filesystem> that
270// depend on something in the dylib.
271#define _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY _LIBCPP_INTRODUCED_IN_LLVM_9
272#define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE
273#define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_PUSH
274#define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_POP
275
276// This controls the availability of the C++20 synchronization library,
277// which requires shared library support for various operations
278// (see libcxx/src/atomic.cpp). This includes <barier>, <latch>,
279// <semaphore>, and notification functions on std::atomic.
280#define _LIBCPP_AVAILABILITY_HAS_SYNC _LIBCPP_INTRODUCED_IN_LLVM_11
281#define _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INTRODUCED_IN_LLVM_11_ATTRIBUTE
216// This controls the availability of new implementation of std::atomic's
217// wait, notify_one and notify_all. The new implementation uses
218// the native atomic wait/notify operations on platforms that support them
219// based on the size of the atomic type, instead of the type itself.
220#define _LIBCPP_AVAILABILITY_HAS_NEW_SYNC _LIBCPP_INTRODUCED_IN_LLVM_22
221#define _LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_INTRODUCED_IN_LLVM_22_ATTRIBUTE
282222
283223// Enable additional explicit instantiations of iostreams components. This
284224// reduces the number of weak definitions generated in programs that use
......@@ -307,7 +247,7 @@
307247// This controls the availability of the C++17 std::pmr library,
308248// which is implemented in large part in the built library.
309249//
310// TODO: Enable std::pmr markup once https://github.com/llvm/llvm-project/issues/40340 has been fixed
250// TODO: Enable std::pmr markup once https://llvm.org/PR40340 has been fixed
311251// Until then, it is possible for folks to try to use `std::pmr` when back-deploying to targets that don't support
312252// it and it'll be a load-time error, but we don't have a good alternative because the library won't compile if we
313253// use availability annotations until that bug has been fixed.
......@@ -364,4 +304,11 @@
364304# define _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION
365305#endif
366306
307// Only define a bunch of symbols in the dylib if we need to be compatible with LLVM 7 headers or older
308# if defined(_LIBCPP_BUILDING_LIBRARY) && _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 8
309# define _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8
310# else
311# define _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 _LIBCPP_HIDE_FROM_ABI
312# endif
313
367314#endif // _LIBCPP___CONFIGURATION_AVAILABILITY_H
lib/libcxx/include/__configuration/compiler.h+6-6
......@@ -33,16 +33,16 @@
3333// Warn if a compiler version is used that is not supported anymore
3434// LLVM RELEASE Update the minimum compiler versions
3535# if defined(_LIBCPP_CLANG_VER)
36# if _LIBCPP_CLANG_VER < 1900
37# warning "Libc++ only supports Clang 19 and later"
36# if _LIBCPP_CLANG_VER < 2001
37# warning "Libc++ only supports Clang 20 and later"
3838# endif
3939# elif defined(_LIBCPP_APPLE_CLANG_VER)
40# if _LIBCPP_APPLE_CLANG_VER < 1500
41# warning "Libc++ only supports AppleClang 15 and later"
40# if _LIBCPP_APPLE_CLANG_VER < 1700
41# warning "Libc++ only supports AppleClang 26 and later"
4242# endif
4343# elif defined(_LIBCPP_GCC_VER)
44# if _LIBCPP_GCC_VER < 1400
45# warning "Libc++ only supports GCC 14 and later"
44# if _LIBCPP_GCC_VER < 1500
45# warning "Libc++ only supports GCC 15 and later"
4646# endif
4747# endif
4848
lib/libcxx/include/__configuration/experimental.h created+38
......@@ -0,0 +1,38 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___CONFIGURATION_EXPERIMENTAL_H
10#define _LIBCPP___CONFIGURATION_EXPERIMENTAL_H
11
12/* zig patch: instead of including __config_site, zig adds -D flags when compiling */
13
14#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
15# pragma GCC system_header
16#endif
17
18#if __has_feature(experimental_library)
19# ifndef _LIBCPP_ENABLE_EXPERIMENTAL
20# define _LIBCPP_ENABLE_EXPERIMENTAL
21# endif
22#endif
23
24// Incomplete features get their own specific disabling flags. This makes it
25// easier to grep for target specific flags once the feature is complete.
26#if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY)
27# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1
28#else
29# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0
30#endif
31
32#define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
33#define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
34#define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
35#define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
36#define _LIBCPP_HAS_EXPERIMENTAL_OPTIONAL_ITERATOR _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
37
38#endif // _LIBCPP___CONFIGURATION_EXPERIMENTAL_H
lib/libcxx/include/__configuration/hardening.h created+215
......@@ -0,0 +1,215 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___CONFIGURATION_HARDENING_H
10#define _LIBCPP___CONFIGURATION_HARDENING_H
11
12/* zig patch: instead of including __config_site, zig adds -D flags when compiling */
13#include <__configuration/experimental.h>
14#include <__configuration/language.h>
15
16#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
17# pragma GCC system_header
18#endif
19
20// TODO(LLVM 23): Remove this. We're making these an error to catch folks who might not have migrated.
21// Since hardening went through several changes (many of which impacted user-facing macros),
22// we're keeping these checks around for a bit longer than usual. Failure to properly configure
23// hardening results in checks being dropped silently, which is a pretty big deal.
24#if defined(_LIBCPP_ENABLE_ASSERTIONS)
25# error "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
26#endif
27#if defined(_LIBCPP_ENABLE_HARDENED_MODE)
28# error "_LIBCPP_ENABLE_HARDENED_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
29#endif
30#if defined(_LIBCPP_ENABLE_SAFE_MODE)
31# error "_LIBCPP_ENABLE_SAFE_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
32#endif
33#if defined(_LIBCPP_ENABLE_DEBUG_MODE)
34# error "_LIBCPP_ENABLE_DEBUG_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
35#endif
36
37// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values:
38//
39// - `_LIBCPP_HARDENING_MODE_NONE`;
40// - `_LIBCPP_HARDENING_MODE_FAST`;
41// - `_LIBCPP_HARDENING_MODE_EXTENSIVE`;
42// - `_LIBCPP_HARDENING_MODE_DEBUG`.
43//
44// These values have the following effects:
45//
46// - `_LIBCPP_HARDENING_MODE_NONE` -- sets the hardening mode to "none" which disables all runtime hardening checks;
47//
48// - `_LIBCPP_HARDENING_MODE_FAST` -- sets that hardening mode to "fast". The fast mode enables security-critical checks
49// that can be done with relatively little runtime overhead in constant time;
50//
51// - `_LIBCPP_HARDENING_MODE_EXTENSIVE` -- sets the hardening mode to "extensive". The extensive mode is a superset of
52// the fast mode that additionally enables checks that are relatively cheap and prevent common types of logic errors
53// but are not necessarily security-critical;
54//
55// - `_LIBCPP_HARDENING_MODE_DEBUG` -- sets the hardening mode to "debug". The debug mode is a superset of the extensive
56// mode and enables all checks available in the library, including internal assertions. Checks that are part of the
57// debug mode can be very expensive and thus the debug mode is intended to be used for testing, not in production.
58
59// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These
60// macros are only for internal use -- users should only pick one of the high-level hardening modes described above.
61//
62// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and
63// a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid:
64// - the sentinel is reachable from the begin iterator;
65// - TODO(hardening): both iterators refer to the same container.
66//
67// - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through
68// the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access
69// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like
70// `optional` and `function` are considered one-element containers for the purposes of this check.
71//
72// - `_LIBCPP_ASSERT_NON_NULL` -- checks that the pointer being dereferenced is not null. On most modern platforms zero
73// address does not refer to an actual location in memory, so a null pointer dereference would not compromize the
74// memory security of a program (however, it is still undefined behavior that can result in strange errors due to
75// compiler optimizations).
76//
77// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the
78// given ranges do not overlap.
79//
80// - `_LIBCPP_ASSERT_VALID_DEALLOCATION` -- checks that an attempt to deallocate memory is valid (e.g. the given object
81// was allocated by the given allocator). Violating this category typically results in a memory leak.
82//
83// - `_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL` -- checks that a call to an external API doesn't fail in
84// an unexpected manner. This includes triggering documented cases of undefined behavior in an external library (like
85// attempting to unlock an unlocked mutex in pthreads). Any API external to the library falls under this category
86// (from system calls to compiler intrinsics). We generally don't expect these failures to compromize memory safety or
87// otherwise create an immediate security issue.
88//
89// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure
90// the containers have compatible allocators.
91//
92// - `_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN` -- checks that the given argument is within the domain of valid arguments
93// for the function. Violating this typically produces an incorrect result (e.g. the clamp algorithm returns the
94// original value without clamping it due to incorrect functors) or puts an object into an invalid state (e.g.
95// a string view where only a subset of elements is possible to access). This category is for assertions violating
96// which doesn't cause any immediate issues in the library -- whatever the consequences are, they will happen in the
97// user code.
98//
99// - `_LIBCPP_ASSERT_PEDANTIC` -- checks prerequisites which are imposed by the Standard, but violating which happens to
100// be benign in our implementation.
101//
102// - `_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT` -- checks that the given argument satisfies the semantic requirements imposed
103// by the Standard. Typically, there is no simple way to completely prove that a semantic requirement is satisfied;
104// thus, this would often be a heuristic check and it might be quite expensive.
105//
106// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on
107// user input.
108//
109// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet.
110
111// clang-format off
112# define _LIBCPP_HARDENING_MODE_NONE (1 << 1)
113# define _LIBCPP_HARDENING_MODE_FAST (1 << 2)
114# define _LIBCPP_HARDENING_MODE_EXTENSIVE (1 << 4) // Deliberately not ordered.
115# define _LIBCPP_HARDENING_MODE_DEBUG (1 << 3)
116// clang-format on
117
118#ifndef _LIBCPP_HARDENING_MODE
119
120# ifndef _LIBCPP_HARDENING_MODE_DEFAULT
121# error _LIBCPP_HARDENING_MODE_DEFAULT is not defined. This definition should be set at configuration time in the \
122`__config_site` header, please make sure your installation of libc++ is not broken.
123# endif
124
125# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT
126#endif
127
128#if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_NONE && _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_FAST && \
129 _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_EXTENSIVE && \
130 _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
131# error _LIBCPP_HARDENING_MODE must be set to one of the following values: \
132_LIBCPP_HARDENING_MODE_NONE, \
133_LIBCPP_HARDENING_MODE_FAST, \
134_LIBCPP_HARDENING_MODE_EXTENSIVE, \
135_LIBCPP_HARDENING_MODE_DEBUG
136#endif
137
138// The library provides the macro `_LIBCPP_ASSERTION_SEMANTIC` for configuring the assertion semantic used by hardening;
139// it can be set to one of the following values:
140//
141// - `_LIBCPP_ASSERTION_SEMANTIC_IGNORE`;
142// - `_LIBCPP_ASSERTION_SEMANTIC_OBSERVE`;
143// - `_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE`;
144// - `_LIBCPP_ASSERTION_SEMANTIC_ENFORCE`.
145//
146// libc++ assertion semantics generally mirror the evaluation semantics of C++26 Contracts:
147// - `ignore` evaluates the assertion but doesn't do anything if it fails (note that it differs from the Contracts
148// `ignore` semantic which wouldn't evaluate the assertion at all);
149// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution;
150// - `quick-enforce` terminates the program as fast as possible (via trapping);
151// - `enforce` logs an error and then terminates the program.
152//
153// Additionally, a special `hardening-dependent` value selects the assertion semantic based on the hardening mode in
154// effect: the production-capable modes (`fast` and `extensive`) map to `quick_enforce` and the `debug` mode maps to
155// `enforce`. The `hardening-dependent` semantic cannot be selected explicitly, it is only used when no assertion
156// semantic is provided by the user _and_ the library's default semantic is configured to be dependent on hardening.
157//
158// Notes:
159// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant
160// to make adopting hardening easier but should not be used outside of this scenario;
161// - C++26 wording for Library Hardening precludes a conforming Hardened implementation from using the Contracts
162// `ignore` semantic when evaluating hardened preconditions in the Library. Libc++ allows using this semantic for
163// hardened preconditions, however, be aware that using `ignore` does not produce a conforming "Hardened"
164// implementation, unlike the other semantics above.
165// clang-format off
166# define _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT (1 << 1)
167# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 2)
168# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 3)
169# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 4)
170# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 5)
171// clang-format on
172
173// If the user attempts to configure the assertion semantic, check that it is allowed in the current environment.
174#if defined(_LIBCPP_ASSERTION_SEMANTIC)
175# if !_LIBCPP_HAS_EXPERIMENTAL_LIBRARY
176# error "Assertion semantics are an experimental feature."
177# endif
178# if defined(_LIBCPP_CXX03_LANG)
179# error "Assertion semantics are not available in the C++03 mode."
180# endif
181#endif // defined(_LIBCPP_ASSERTION_SEMANTIC)
182
183// User-provided semantic takes top priority -- don't override if set.
184#ifndef _LIBCPP_ASSERTION_SEMANTIC
185
186# ifndef _LIBCPP_ASSERTION_SEMANTIC_DEFAULT
187# error _LIBCPP_ASSERTION_SEMANTIC_DEFAULT is not defined. This definition should be set at configuration time in \
188the `__config_site` header, please make sure your installation of libc++ is not broken.
189# endif
190
191# if _LIBCPP_ASSERTION_SEMANTIC_DEFAULT != _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT
192# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_DEFAULT
193# else
194# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
195# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
196# else
197# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
198# endif
199# endif // _LIBCPP_ASSERTION_SEMANTIC_DEFAULT != _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT
200
201#endif // #ifndef _LIBCPP_ASSERTION_SEMANTIC
202
203// Finally, validate the selected semantic (in case the user tries setting it to an incorrect value):
204#if _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_IGNORE && \
205 _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_OBSERVE && \
206 _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE && \
207 _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
208# error _LIBCPP_ASSERTION_SEMANTIC must be set to one of the following values: \
209_LIBCPP_ASSERTION_SEMANTIC_IGNORE, \
210_LIBCPP_ASSERTION_SEMANTIC_OBSERVE, \
211_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE, \
212_LIBCPP_ASSERTION_SEMANTIC_ENFORCE
213#endif
214
215#endif // _LIBCPP___CONFIGURATION_HARDENING_H
lib/libcxx/include/__configuration/language.h+3
......@@ -18,6 +18,9 @@
1818
1919// NOLINTBEGIN(libcpp-cpp-version-check)
2020#ifdef __cplusplus
21# if __cplusplus < 201103L
22# define _LIBCPP_CXX03_LANG
23# endif
2124# if __cplusplus <= 201103L
2225# define _LIBCPP_STD_VER 11
2326# elif __cplusplus <= 201402L
lib/libcxx/include/__configuration/platform.h+9-16
......@@ -31,22 +31,15 @@
3131#endif
3232
3333// Need to detect which libc we're using if we're on Linux.
34#if defined(__linux__) || defined(__AMDGPU__) || defined(__NVPTX__)
35# if __has_include(<features.h>)
36# include <features.h>
37# if defined(__GLIBC_PREREQ)
38# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b)
39# else
40# define _LIBCPP_GLIBC_PREREQ(a, b) 0
41# endif // defined(__GLIBC_PREREQ)
42# endif
43#endif
44
45// This is required in order for _NEWLIB_VERSION to be defined in places where we use it.
46// TODO: We shouldn't be including arbitrarily-named headers from libc++ since this can break valid
47// user code. Move code paths that need _NEWLIB_VERSION to another customization mechanism.
48#if __has_include(<picolibc.h>)
49# include <picolibc.h>
34#if (defined(__linux__) || defined(__AMDGPU__) || defined(__NVPTX__)) && __has_include(<features.h>)
35# include <features.h>
36# if defined(__GLIBC_PREREQ)
37# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b)
38# else
39# define _LIBCPP_GLIBC_PREREQ(a, b) 0
40# endif // defined(__GLIBC_PREREQ)
41#else
42# define _LIBCPP_GLIBC_PREREQ(a, b) 0
5043#endif
5144
5245#ifndef __BYTE_ORDER__
lib/libcxx/include/__coroutine/coroutine_handle.h+9-9
......@@ -44,9 +44,9 @@ public:
4444 }
4545
4646 // [coroutine.handle.export.import], export/import
47 _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
47 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
4848
49 _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
49 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
5050 coroutine_handle __tmp;
5151 __tmp.__handle_ = __addr;
5252 return __tmp;
......@@ -55,7 +55,7 @@ public:
5555 // [coroutine.handle.observers], observers
5656 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; }
5757
58 _LIBCPP_HIDE_FROM_ABI bool done() const {
58 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool done() const {
5959 _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines");
6060 return __builtin_coro_done(__handle_);
6161 }
......@@ -100,7 +100,7 @@ public:
100100
101101 _LIBCPP_HIDE_FROM_ABI constexpr coroutine_handle(nullptr_t) noexcept {}
102102
103 _LIBCPP_HIDE_FROM_ABI static coroutine_handle from_promise(_Promise& __promise) {
103 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static coroutine_handle from_promise(_Promise& __promise) {
104104 using _RawPromise = __remove_cv_t<_Promise>;
105105 coroutine_handle __tmp;
106106 __tmp.__handle_ =
......@@ -114,9 +114,9 @@ public:
114114 }
115115
116116 // [coroutine.handle.export.import], export/import
117 _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
117 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
118118
119 _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
119 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
120120 coroutine_handle __tmp;
121121 __tmp.__handle_ = __addr;
122122 return __tmp;
......@@ -130,7 +130,7 @@ public:
130130 // [coroutine.handle.observers], observers
131131 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; }
132132
133 _LIBCPP_HIDE_FROM_ABI bool done() const {
133 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool done() const {
134134 _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines");
135135 return __builtin_coro_done(__handle_);
136136 }
......@@ -150,7 +150,7 @@ public:
150150 }
151151
152152 // [coroutine.handle.promise], promise access
153 _LIBCPP_HIDE_FROM_ABI _Promise& promise() const {
153 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Promise& promise() const {
154154 return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false));
155155 }
156156
......@@ -165,7 +165,7 @@ private:
165165// [coroutine.handle.hash]
166166template <class _Tp>
167167struct hash<coroutine_handle<_Tp>> {
168 _LIBCPP_HIDE_FROM_ABI size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept {
168 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept {
169169 return hash<void*>()(__v.address());
170170 }
171171};
lib/libcxx/include/__coroutine/noop_coroutine_handle.h+11-13
......@@ -20,8 +20,6 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23# if __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC)
24
2523// [coroutine.noop]
2624// [coroutine.promise.noop]
2725struct noop_coroutine_promise {};
......@@ -37,7 +35,7 @@ public:
3735
3836 // [coroutine.handle.noop.observers], observers
3937 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return true; }
40 _LIBCPP_HIDE_FROM_ABI constexpr bool done() const noexcept { return false; }
38 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool done() const noexcept { return false; }
4139
4240 // [coroutine.handle.noop.resumption], resumption
4341 _LIBCPP_HIDE_FROM_ABI constexpr void operator()() const noexcept {}
......@@ -45,23 +43,23 @@ public:
4543 _LIBCPP_HIDE_FROM_ABI constexpr void destroy() const noexcept {}
4644
4745 // [coroutine.handle.noop.promise], promise access
48 _LIBCPP_HIDE_FROM_ABI noop_coroutine_promise& promise() const noexcept {
46 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI noop_coroutine_promise& promise() const noexcept {
4947 return *static_cast<noop_coroutine_promise*>(
5048 __builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false));
5149 }
5250
5351 // [coroutine.handle.noop.address], address
54 _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
52 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
5553
5654private:
5755 _LIBCPP_HIDE_FROM_ABI friend coroutine_handle<noop_coroutine_promise> noop_coroutine() noexcept;
5856
59# if __has_builtin(__builtin_coro_noop)
57# if __has_builtin(__builtin_coro_noop)
6058 _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept { this->__handle_ = __builtin_coro_noop(); }
6159
6260 void* __handle_ = nullptr;
6361
64# elif defined(_LIBCPP_COMPILER_GCC)
62# elif defined(_LIBCPP_COMPILER_GCC)
6563 // GCC doesn't implement __builtin_coro_noop().
6664 // Construct the coroutine frame manually instead.
6765 struct __noop_coroutine_frame_ty_ {
......@@ -78,19 +76,19 @@ private:
7876
7977 _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept = default;
8078
81# endif // __has_builtin(__builtin_coro_noop)
79# endif // __has_builtin(__builtin_coro_noop)
8280};
8381
8482using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
8583
86# if defined(_LIBCPP_COMPILER_GCC)
84# if defined(_LIBCPP_COMPILER_GCC)
8785inline noop_coroutine_handle::__noop_coroutine_frame_ty_ noop_coroutine_handle::__noop_coroutine_frame_{};
88# endif
86# endif
8987
9088// [coroutine.noop.coroutine]
91inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); }
92
93# endif // __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC)
89[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept {
90 return noop_coroutine_handle();
91}
9492
9593_LIBCPP_END_NAMESPACE_STD
9694
lib/libcxx/include/__debug_utils/strict_weak_ordering_check.h+1-1
......@@ -27,7 +27,7 @@ template <class _RandomAccessIterator, class _Comp>
2727_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
2828__check_strict_weak_ordering_sorted(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
2929#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
30 using __diff_t = __iter_diff_t<_RandomAccessIterator>;
30 using __diff_t = __iterator_difference_type<_RandomAccessIterator>;
3131 using _Comp_ref = __comp_ref_type<_Comp>;
3232 if (!__libcpp_is_constant_evaluated()) {
3333 // Check if the range is actually sorted.
lib/libcxx/include/__exception/exception.h+6-4
......@@ -48,13 +48,15 @@ public:
4848 __data_._DoFree = true;
4949 }
5050
51 exception(exception const&) _NOEXCEPT {}
51 exception(exception const&) _NOEXCEPT : __data_() {}
5252
5353 exception& operator=(exception const&) _NOEXCEPT { return *this; }
5454
5555 virtual ~exception() _NOEXCEPT {}
5656
57 virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; }
57 [[__nodiscard__]] virtual char const* what() const _NOEXCEPT {
58 return __data_._What ? __data_._What : "Unknown exception";
59 }
5860
5961private:
6062 __std_exception_data __data_;
......@@ -76,7 +78,7 @@ public:
7678 _LIBCPP_HIDE_FROM_ABI exception& operator=(const exception&) _NOEXCEPT = default;
7779
7880 virtual ~exception() _NOEXCEPT;
79 virtual const char* what() const _NOEXCEPT;
81 [[__nodiscard__]] virtual const char* what() const _NOEXCEPT;
8082};
8183
8284class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception {
......@@ -85,7 +87,7 @@ public:
8587 _LIBCPP_HIDE_FROM_ABI bad_exception(const bad_exception&) _NOEXCEPT = default;
8688 _LIBCPP_HIDE_FROM_ABI bad_exception& operator=(const bad_exception&) _NOEXCEPT = default;
8789 ~bad_exception() _NOEXCEPT override;
88 const char* what() const _NOEXCEPT override;
90 [[__nodiscard__]] const char* what() const _NOEXCEPT override;
8991};
9092#endif // !_LIBCPP_ABI_VCRUNTIME
9193
lib/libcxx/include/__exception/exception_ptr.h+27-5
......@@ -11,18 +11,24 @@
1111
1212#include <__config>
1313#include <__cstddef/nullptr_t.h>
14#include <__cstddef/size_t.h>
1415#include <__exception/operations.h>
1516#include <__memory/addressof.h>
1617#include <__memory/construct_at.h>
1718#include <__type_traits/decay.h>
1819#include <__type_traits/is_pointer.h>
19#include <cstdlib>
20#include <__utility/move.h>
21#include <__utility/swap.h>
22#include <__verbose_abort>
2023#include <typeinfo>
2124
2225#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2326# pragma GCC system_header
2427#endif
2528
29_LIBCPP_PUSH_MACROS
30#include <__undef_macros>
31
2632#ifndef _LIBCPP_ABI_MICROSOFT
2733
2834# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
......@@ -30,7 +36,7 @@
3036namespace __cxxabiv1 {
3137
3238extern "C" {
33_LIBCPP_OVERRIDABLE_FUNC_VIS void* __cxa_allocate_exception(size_t) throw();
39_LIBCPP_OVERRIDABLE_FUNC_VIS void* __cxa_allocate_exception(std::size_t) throw();
3440_LIBCPP_OVERRIDABLE_FUNC_VIS void __cxa_free_exception(void*) throw();
3541
3642struct __cxa_exception;
......@@ -57,6 +63,8 @@ _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
5763
5864#ifndef _LIBCPP_ABI_MICROSOFT
5965
66inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT;
67
6068class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
6169 void* __ptr_;
6270
......@@ -67,15 +75,21 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
6775
6876public:
6977 // exception_ptr is basically a COW string so it is trivially relocatable.
70 // It is also replaceable because assignment has normal value semantics.
7178 using __trivially_relocatable _LIBCPP_NODEBUG = exception_ptr;
72 using __replaceable _LIBCPP_NODEBUG = exception_ptr;
7379
7480 _LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {}
7581 _LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
7682
7783 exception_ptr(const exception_ptr&) _NOEXCEPT;
84 _LIBCPP_HIDE_FROM_ABI exception_ptr(exception_ptr&& __other) _NOEXCEPT : __ptr_(__other.__ptr_) {
85 __other.__ptr_ = nullptr;
86 }
7887 exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
88 _LIBCPP_HIDE_FROM_ABI exception_ptr& operator=(exception_ptr&& __other) _NOEXCEPT {
89 exception_ptr __tmp(std::move(__other));
90 std::swap(__tmp, *this);
91 return *this;
92 }
7993 ~exception_ptr() _NOEXCEPT;
8094
8195 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_ != nullptr; }
......@@ -88,10 +102,16 @@ public:
88102 return !(__x == __y);
89103 }
90104
105 friend _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT;
106
91107 friend _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
92108 friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
93109};
94110
111inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT {
112 std::swap(__x.__ptr_, __y.__ptr_);
113}
114
95115# if _LIBCPP_HAS_EXCEPTIONS
96116# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
97117template <class _Ep>
......@@ -153,7 +173,7 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
153173# else // !_LIBCPP_HAS_EXCEPTIONS
154174template <class _Ep>
155175_LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep) _NOEXCEPT {
156 std::abort();
176 _LIBCPP_VERBOSE_ABORT("make_exception_ptr was called in -fno-exceptions mode");
157177}
158178# endif // _LIBCPP_HAS_EXCEPTIONS
159179
......@@ -201,4 +221,6 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
201221#endif // _LIBCPP_ABI_MICROSOFT
202222_LIBCPP_END_UNVERSIONED_NAMESPACE_STD
203223
224_LIBCPP_POP_MACROS
225
204226#endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
lib/libcxx/include/__exception/nested_exception.h+2-2
......@@ -40,7 +40,7 @@ public:
4040
4141 // access functions
4242 [[__noreturn__]] void rethrow_nested() const;
43 _LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; }
43 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; }
4444};
4545
4646template <class _Tp>
......@@ -73,7 +73,7 @@ template <class _Tp>
7373 __throw_with_nested<_Tp,
7474 _Up,
7575 is_class<_Up>::value && !is_base_of<nested_exception, _Up>::value &&
76 !__libcpp_is_final<_Up>::value>::__do_throw(std::forward<_Tp>(__t));
76 !__is_final_v<_Up> >::__do_throw(std::forward<_Tp>(__t));
7777#else
7878 ((void)__t);
7979 // FIXME: Make this abort
lib/libcxx/include/__exception/operations.h+5-5
......@@ -20,22 +20,22 @@ _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
2020 defined(_LIBCPP_BUILDING_LIBRARY)
2121using unexpected_handler = void (*)();
2222_LIBCPP_EXPORTED_FROM_ABI unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
23_LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT;
23[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT;
2424[[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void unexpected();
2525#endif
2626
2727using terminate_handler = void (*)();
2828_LIBCPP_EXPORTED_FROM_ABI terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
29_LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT;
29[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT;
3030
3131#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
32_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT;
32[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT;
3333#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
34_LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT;
34[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT;
3535
3636class _LIBCPP_EXPORTED_FROM_ABI exception_ptr;
3737
38_LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
38[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
3939[[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
4040_LIBCPP_END_UNVERSIONED_NAMESPACE_STD
4141
lib/libcxx/include/__expected/bad_expected_access.h+8-6
......@@ -43,9 +43,11 @@ protected:
4343
4444public:
4545# if _LIBCPP_AVAILABILITY_HAS_BAD_EXPECTED_ACCESS_KEY_FUNCTION
46 const char* what() const noexcept override;
46 [[nodiscard]] const char* what() const noexcept override;
4747# else
48 _LIBCPP_HIDE_FROM_ABI_VIRTUAL const char* what() const noexcept override { return "bad access to std::expected"; }
48 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI_VIRTUAL const char* what() const noexcept override {
49 return "bad access to std::expected";
50 }
4951# endif
5052};
5153_LIBCPP_DIAGNOSTIC_POP
......@@ -55,10 +57,10 @@ class bad_expected_access : public bad_expected_access<void> {
5557public:
5658 _LIBCPP_HIDE_FROM_ABI explicit bad_expected_access(_Err __e) : __unex_(std::move(__e)) {}
5759
58 _LIBCPP_HIDE_FROM_ABI _Err& error() & noexcept { return __unex_; }
59 _LIBCPP_HIDE_FROM_ABI const _Err& error() const& noexcept { return __unex_; }
60 _LIBCPP_HIDE_FROM_ABI _Err&& error() && noexcept { return std::move(__unex_); }
61 _LIBCPP_HIDE_FROM_ABI const _Err&& error() const&& noexcept { return std::move(__unex_); }
60 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Err& error() & noexcept { return __unex_; }
61 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const _Err& error() const& noexcept { return __unex_; }
62 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Err&& error() && noexcept { return std::move(__unex_); }
63 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const _Err&& error() const&& noexcept { return std::move(__unex_); }
6264
6365private:
6466 _Err __unex_;
lib/libcxx/include/__expected/expected.h+62-64
......@@ -30,7 +30,6 @@
3030#include <__type_traits/is_nothrow_assignable.h>
3131#include <__type_traits/is_nothrow_constructible.h>
3232#include <__type_traits/is_reference.h>
33#include <__type_traits/is_replaceable.h>
3433#include <__type_traits/is_same.h>
3534#include <__type_traits/is_swappable.h>
3635#include <__type_traits/is_trivially_constructible.h>
......@@ -472,8 +471,6 @@ public:
472471 __conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value && __libcpp_is_trivially_relocatable<_Err>::value,
473472 expected,
474473 void>;
475 using __replaceable _LIBCPP_NODEBUG =
476 __conditional_t<__is_replaceable_v<_Tp> && __is_replaceable_v<_Err>, expected, void>;
477474
478475 template <class _Up>
479476 using rebind = expected<_Up, error_type>;
......@@ -555,9 +552,10 @@ public:
555552 is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
556553 : __base(__other.__has_val(), std::move(__other.__union())) {}
557554
558 template <class _Up = _Tp>
555 template <class _Up = remove_cv_t<_Tp>>
559556 requires(!is_same_v<remove_cvref_t<_Up>, in_place_t> && !is_same_v<expected, remove_cvref_t<_Up>> &&
560 is_constructible_v<_Tp, _Up> && !__is_std_unexpected<remove_cvref_t<_Up>>::value &&
557 !is_same_v<remove_cvref_t<_Up>, unexpect_t> && is_constructible_v<_Tp, _Up> &&
558 !__is_std_unexpected<remove_cvref_t<_Up>>::value &&
561559 (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_expected<remove_cvref_t<_Up>>::value))
562560 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>)
563561 expected(_Up&& __u) noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened
......@@ -668,7 +666,7 @@ public:
668666 return *this;
669667 }
670668
671 template <class _Up = _Tp>
669 template <class _Up = remove_cv_t<_Tp>>
672670 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v)
673671 requires(!is_same_v<expected, remove_cvref_t<_Up>> && !__is_std_unexpected<remove_cvref_t<_Up>>::value &&
674672 is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up> &&
......@@ -800,25 +798,25 @@ public:
800798 return std::addressof(this->__val());
801799 }
802800
803 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept {
801 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept {
804802 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
805803 this->__has_val(), "expected::operator* requires the expected to contain a value");
806804 return this->__val();
807805 }
808806
809 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept {
807 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept {
810808 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
811809 this->__has_val(), "expected::operator* requires the expected to contain a value");
812810 return this->__val();
813811 }
814812
815 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept {
813 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept {
816814 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
817815 this->__has_val(), "expected::operator* requires the expected to contain a value");
818816 return std::move(this->__val());
819817 }
820818
821 _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept {
819 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept {
822820 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
823821 this->__has_val(), "expected::operator* requires the expected to contain a value");
824822 return std::move(this->__val());
......@@ -826,9 +824,9 @@ public:
826824
827825 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return this->__has_val(); }
828826
829 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__has_val(); }
827 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__has_val(); }
830828
831 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& {
829 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& {
832830 static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
833831 if (!this->__has_val()) {
834832 std::__throw_bad_expected_access<_Err>(std::as_const(error()));
......@@ -836,7 +834,7 @@ public:
836834 return this->__val();
837835 }
838836
839 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & {
837 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & {
840838 static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
841839 if (!this->__has_val()) {
842840 std::__throw_bad_expected_access<_Err>(std::as_const(error()));
......@@ -844,7 +842,7 @@ public:
844842 return this->__val();
845843 }
846844
847 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& {
845 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& {
848846 static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>,
849847 "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
850848 if (!this->__has_val()) {
......@@ -853,7 +851,7 @@ public:
853851 return std::move(this->__val());
854852 }
855853
856 _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && {
854 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && {
857855 static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>,
858856 "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
859857 if (!this->__has_val()) {
......@@ -862,46 +860,46 @@ public:
862860 return std::move(this->__val());
863861 }
864862
865 _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
863 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
866864 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
867865 !this->__has_val(), "expected::error requires the expected to contain an error");
868866 return this->__unex();
869867 }
870868
871 _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
869 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
872870 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
873871 !this->__has_val(), "expected::error requires the expected to contain an error");
874872 return this->__unex();
875873 }
876874
877 _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
875 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
878876 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
879877 !this->__has_val(), "expected::error requires the expected to contain an error");
880878 return std::move(this->__unex());
881879 }
882880
883 _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
881 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
884882 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
885883 !this->__has_val(), "expected::error requires the expected to contain an error");
886884 return std::move(this->__unex());
887885 }
888886
889 template <class _Up>
890 _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& {
887 template <class _Up = remove_cv_t<_Tp>>
888 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& {
891889 static_assert(is_copy_constructible_v<_Tp>, "value_type has to be copy constructible");
892890 static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
893891 return this->__has_val() ? this->__val() : static_cast<_Tp>(std::forward<_Up>(__v));
894892 }
895893
896 template <class _Up>
897 _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
894 template <class _Up = remove_cv_t<_Tp>>
895 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
898896 static_assert(is_move_constructible_v<_Tp>, "value_type has to be move constructible");
899897 static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
900898 return this->__has_val() ? std::move(this->__val()) : static_cast<_Tp>(std::forward<_Up>(__v));
901899 }
902900
903901 template <class _Up = _Err>
904 _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
902 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
905903 static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
906904 static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
907905 if (has_value())
......@@ -910,7 +908,7 @@ public:
910908 }
911909
912910 template <class _Up = _Err>
913 _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
911 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
914912 static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible");
915913 static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
916914 if (has_value())
......@@ -921,7 +919,7 @@ public:
921919 // [expected.void.monadic], monadic
922920 template <class _Func>
923921 requires is_constructible_v<_Err, _Err&>
924 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
922 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
925923 using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&>>;
926924 static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected");
927925 static_assert(is_same_v<typename _Up::error_type, _Err>,
......@@ -934,7 +932,7 @@ public:
934932
935933 template <class _Func>
936934 requires is_constructible_v<_Err, const _Err&>
937 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
935 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
938936 using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&>>;
939937 static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected");
940938 static_assert(is_same_v<typename _Up::error_type, _Err>,
......@@ -947,7 +945,7 @@ public:
947945
948946 template <class _Func>
949947 requires is_constructible_v<_Err, _Err&&>
950 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
948 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
951949 using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&&>>;
952950 static_assert(
953951 __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected");
......@@ -961,7 +959,7 @@ public:
961959
962960 template <class _Func>
963961 requires is_constructible_v<_Err, const _Err&&>
964 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
962 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
965963 using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>;
966964 static_assert(
967965 __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected");
......@@ -975,7 +973,7 @@ public:
975973
976974 template <class _Func>
977975 requires is_constructible_v<_Tp, _Tp&>
978 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
976 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
979977 using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>;
980978 static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
981979 static_assert(is_same_v<typename _Gp::value_type, _Tp>,
......@@ -988,7 +986,7 @@ public:
988986
989987 template <class _Func>
990988 requires is_constructible_v<_Tp, const _Tp&>
991 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
989 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
992990 using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>;
993991 static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
994992 static_assert(is_same_v<typename _Gp::value_type, _Tp>,
......@@ -1001,7 +999,7 @@ public:
1001999
10021000 template <class _Func>
10031001 requires is_constructible_v<_Tp, _Tp&&>
1004 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
1002 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
10051003 using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>;
10061004 static_assert(
10071005 __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
......@@ -1015,7 +1013,7 @@ public:
10151013
10161014 template <class _Func>
10171015 requires is_constructible_v<_Tp, const _Tp&&>
1018 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
1016 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
10191017 using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>;
10201018 static_assert(
10211019 __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
......@@ -1029,7 +1027,7 @@ public:
10291027
10301028 template <class _Func>
10311029 requires is_constructible_v<_Err, _Err&>
1032 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
1030 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
10331031 using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&>>;
10341032 if (!has_value()) {
10351033 return expected<_Up, _Err>(unexpect, error());
......@@ -1045,7 +1043,7 @@ public:
10451043
10461044 template <class _Func>
10471045 requires is_constructible_v<_Err, const _Err&>
1048 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
1046 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
10491047 using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&>>;
10501048 if (!has_value()) {
10511049 return expected<_Up, _Err>(unexpect, error());
......@@ -1061,7 +1059,7 @@ public:
10611059
10621060 template <class _Func>
10631061 requires is_constructible_v<_Err, _Err&&>
1064 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
1062 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
10651063 using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&&>>;
10661064 if (!has_value()) {
10671065 return expected<_Up, _Err>(unexpect, std::move(error()));
......@@ -1077,7 +1075,7 @@ public:
10771075
10781076 template <class _Func>
10791077 requires is_constructible_v<_Err, const _Err&&>
1080 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
1078 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
10811079 using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&&>>;
10821080 if (!has_value()) {
10831081 return expected<_Up, _Err>(unexpect, std::move(error()));
......@@ -1093,7 +1091,7 @@ public:
10931091
10941092 template <class _Func>
10951093 requires is_constructible_v<_Tp, _Tp&>
1096 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
1094 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
10971095 using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>;
10981096 static_assert(__valid_std_unexpected<_Gp>::value,
10991097 "The result of f(error()) must be a valid template argument for unexpected");
......@@ -1105,7 +1103,7 @@ public:
11051103
11061104 template <class _Func>
11071105 requires is_constructible_v<_Tp, const _Tp&>
1108 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
1106 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
11091107 using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>;
11101108 static_assert(__valid_std_unexpected<_Gp>::value,
11111109 "The result of f(error()) must be a valid template argument for unexpected");
......@@ -1117,7 +1115,7 @@ public:
11171115
11181116 template <class _Func>
11191117 requires is_constructible_v<_Tp, _Tp&&>
1120 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
1118 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
11211119 using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>;
11221120 static_assert(__valid_std_unexpected<_Gp>::value,
11231121 "The result of f(std::move(error())) must be a valid template argument for unexpected");
......@@ -1130,7 +1128,7 @@ public:
11301128
11311129 template <class _Func>
11321130 requires is_constructible_v<_Tp, const _Tp&&>
1133 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
1131 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
11341132 using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>;
11351133 static_assert(__valid_std_unexpected<_Gp>::value,
11361134 "The result of f(std::move(error())) must be a valid template argument for unexpected");
......@@ -1597,7 +1595,7 @@ public:
15971595 // [expected.void.obs], observers
15981596 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return this->__has_val(); }
15991597
1600 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__has_val(); }
1598 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__has_val(); }
16011599
16021600 _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept {
16031601 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
......@@ -1618,32 +1616,32 @@ public:
16181616 }
16191617 }
16201618
1621 _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
1619 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
16221620 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
16231621 !this->__has_val(), "expected::error requires the expected to contain an error");
16241622 return this->__unex();
16251623 }
16261624
1627 _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
1625 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
16281626 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
16291627 !this->__has_val(), "expected::error requires the expected to contain an error");
16301628 return this->__unex();
16311629 }
16321630
1633 _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
1631 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
16341632 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
16351633 !this->__has_val(), "expected::error requires the expected to contain an error");
16361634 return std::move(this->__unex());
16371635 }
16381636
1639 _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
1637 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
16401638 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
16411639 !this->__has_val(), "expected::error requires the expected to contain an error");
16421640 return std::move(this->__unex());
16431641 }
16441642
16451643 template <class _Up = _Err>
1646 _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
1644 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
16471645 static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
16481646 static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
16491647 if (has_value()) {
......@@ -1653,7 +1651,7 @@ public:
16531651 }
16541652
16551653 template <class _Up = _Err>
1656 _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
1654 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
16571655 static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible");
16581656 static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
16591657 if (has_value()) {
......@@ -1665,7 +1663,7 @@ public:
16651663 // [expected.void.monadic], monadic
16661664 template <class _Func>
16671665 requires is_constructible_v<_Err, _Err&>
1668 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
1666 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
16691667 using _Up = remove_cvref_t<invoke_result_t<_Func>>;
16701668 static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
16711669 static_assert(
......@@ -1678,7 +1676,7 @@ public:
16781676
16791677 template <class _Func>
16801678 requires is_constructible_v<_Err, const _Err&>
1681 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
1679 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
16821680 using _Up = remove_cvref_t<invoke_result_t<_Func>>;
16831681 static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
16841682 static_assert(
......@@ -1691,7 +1689,7 @@ public:
16911689
16921690 template <class _Func>
16931691 requires is_constructible_v<_Err, _Err&&>
1694 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
1692 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
16951693 using _Up = remove_cvref_t<invoke_result_t<_Func>>;
16961694 static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
16971695 static_assert(
......@@ -1704,7 +1702,7 @@ public:
17041702
17051703 template <class _Func>
17061704 requires is_constructible_v<_Err, const _Err&&>
1707 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
1705 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
17081706 using _Up = remove_cvref_t<invoke_result_t<_Func>>;
17091707 static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
17101708 static_assert(
......@@ -1716,7 +1714,7 @@ public:
17161714 }
17171715
17181716 template <class _Func>
1719 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
1717 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
17201718 using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>;
17211719 static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
17221720 static_assert(is_same_v<typename _Gp::value_type, _Tp>,
......@@ -1728,7 +1726,7 @@ public:
17281726 }
17291727
17301728 template <class _Func>
1731 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
1729 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
17321730 using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>;
17331731 static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
17341732 static_assert(is_same_v<typename _Gp::value_type, _Tp>,
......@@ -1740,7 +1738,7 @@ public:
17401738 }
17411739
17421740 template <class _Func>
1743 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
1741 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
17441742 using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>;
17451743 static_assert(
17461744 __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
......@@ -1753,7 +1751,7 @@ public:
17531751 }
17541752
17551753 template <class _Func>
1756 _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
1754 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
17571755 using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>;
17581756 static_assert(
17591757 __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
......@@ -1767,7 +1765,7 @@ public:
17671765
17681766 template <class _Func>
17691767 requires is_constructible_v<_Err, _Err&>
1770 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
1768 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
17711769 using _Up = remove_cv_t<invoke_result_t<_Func>>;
17721770 if (!has_value()) {
17731771 return expected<_Up, _Err>(unexpect, error());
......@@ -1782,7 +1780,7 @@ public:
17821780
17831781 template <class _Func>
17841782 requires is_constructible_v<_Err, const _Err&>
1785 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
1783 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
17861784 using _Up = remove_cv_t<invoke_result_t<_Func>>;
17871785 if (!has_value()) {
17881786 return expected<_Up, _Err>(unexpect, error());
......@@ -1797,7 +1795,7 @@ public:
17971795
17981796 template <class _Func>
17991797 requires is_constructible_v<_Err, _Err&&>
1800 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
1798 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
18011799 using _Up = remove_cv_t<invoke_result_t<_Func>>;
18021800 if (!has_value()) {
18031801 return expected<_Up, _Err>(unexpect, std::move(error()));
......@@ -1812,7 +1810,7 @@ public:
18121810
18131811 template <class _Func>
18141812 requires is_constructible_v<_Err, const _Err&&>
1815 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
1813 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
18161814 using _Up = remove_cv_t<invoke_result_t<_Func>>;
18171815 if (!has_value()) {
18181816 return expected<_Up, _Err>(unexpect, std::move(error()));
......@@ -1826,7 +1824,7 @@ public:
18261824 }
18271825
18281826 template <class _Func>
1829 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
1827 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
18301828 using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>;
18311829 static_assert(__valid_std_unexpected<_Gp>::value,
18321830 "The result of f(error()) must be a valid template argument for unexpected");
......@@ -1837,7 +1835,7 @@ public:
18371835 }
18381836
18391837 template <class _Func>
1840 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
1838 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
18411839 using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>;
18421840 static_assert(__valid_std_unexpected<_Gp>::value,
18431841 "The result of f(error()) must be a valid template argument for unexpected");
......@@ -1848,7 +1846,7 @@ public:
18481846 }
18491847
18501848 template <class _Func>
1851 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
1849 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
18521850 using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>;
18531851 static_assert(__valid_std_unexpected<_Gp>::value,
18541852 "The result of f(std::move(error())) must be a valid template argument for unexpected");
......@@ -1860,7 +1858,7 @@ public:
18601858 }
18611859
18621860 template <class _Func>
1863 _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
1861 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
18641862 using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>;
18651863 static_assert(__valid_std_unexpected<_Gp>::value,
18661864 "The result of f(std::move(error())) must be a valid template argument for unexpected");
lib/libcxx/include/__expected/unexpected.h+4-4
......@@ -89,10 +89,10 @@ public:
8989 _LIBCPP_HIDE_FROM_ABI constexpr unexpected& operator=(const unexpected&) = default;
9090 _LIBCPP_HIDE_FROM_ABI constexpr unexpected& operator=(unexpected&&) = default;
9191
92 _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { return __unex_; }
93 _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { return __unex_; }
94 _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { return std::move(__unex_); }
95 _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { return std::move(__unex_); }
92 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { return __unex_; }
93 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { return __unex_; }
94 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { return std::move(__unex_); }
95 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { return std::move(__unex_); }
9696
9797 _LIBCPP_HIDE_FROM_ABI constexpr void swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Err>) {
9898 static_assert(is_swappable_v<_Err>, "unexpected::swap requires is_swappable_v<E> to be true");
lib/libcxx/include/__filesystem/copy_options.h+4-4
......@@ -34,19 +34,19 @@ enum class copy_options : unsigned short {
3434 __in_recursive_copy = 512,
3535};
3636
37_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator&(copy_options __lhs, copy_options __rhs) {
37[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator&(copy_options __lhs, copy_options __rhs) {
3838 return static_cast<copy_options>(static_cast<unsigned short>(__lhs) & static_cast<unsigned short>(__rhs));
3939}
4040
41_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator|(copy_options __lhs, copy_options __rhs) {
41[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator|(copy_options __lhs, copy_options __rhs) {
4242 return static_cast<copy_options>(static_cast<unsigned short>(__lhs) | static_cast<unsigned short>(__rhs));
4343}
4444
45_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator^(copy_options __lhs, copy_options __rhs) {
45[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator^(copy_options __lhs, copy_options __rhs) {
4646 return static_cast<copy_options>(static_cast<unsigned short>(__lhs) ^ static_cast<unsigned short>(__rhs));
4747}
4848
49_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator~(copy_options __lhs) {
49[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator~(copy_options __lhs) {
5050 return static_cast<copy_options>(~static_cast<unsigned short>(__lhs));
5151}
5252
lib/libcxx/include/__filesystem/directory_entry.h+37-33
......@@ -40,8 +40,6 @@ _LIBCPP_PUSH_MACROS
4040
4141_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
4242
43_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
44
4543class directory_entry {
4644 typedef filesystem::path _Path;
4745
......@@ -89,80 +87,88 @@ public:
8987
9088 _LIBCPP_HIDE_FROM_ABI void refresh(error_code& __ec) noexcept { __refresh(&__ec); }
9189
92 _LIBCPP_HIDE_FROM_ABI _Path const& path() const noexcept { return __p_; }
90 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Path const& path() const noexcept { return __p_; }
9391
9492 _LIBCPP_HIDE_FROM_ABI operator const _Path&() const noexcept { return __p_; }
9593
96 _LIBCPP_HIDE_FROM_ABI bool exists() const { return filesystem::exists(file_status{__get_ft()}); }
94 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool exists() const { return filesystem::exists(file_status{__get_ft()}); }
9795
98 _LIBCPP_HIDE_FROM_ABI bool exists(error_code& __ec) const noexcept {
96 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool exists(error_code& __ec) const noexcept {
9997 return filesystem::exists(file_status{__get_ft(&__ec)});
10098 }
10199
102 _LIBCPP_HIDE_FROM_ABI bool is_block_file() const { return __get_ft() == file_type::block; }
100 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_block_file() const { return __get_ft() == file_type::block; }
103101
104 _LIBCPP_HIDE_FROM_ABI bool is_block_file(error_code& __ec) const noexcept {
102 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_block_file(error_code& __ec) const noexcept {
105103 return __get_ft(&__ec) == file_type::block;
106104 }
107105
108 _LIBCPP_HIDE_FROM_ABI bool is_character_file() const { return __get_ft() == file_type::character; }
106 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_character_file() const { return __get_ft() == file_type::character; }
109107
110 _LIBCPP_HIDE_FROM_ABI bool is_character_file(error_code& __ec) const noexcept {
108 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_character_file(error_code& __ec) const noexcept {
111109 return __get_ft(&__ec) == file_type::character;
112110 }
113111
114 _LIBCPP_HIDE_FROM_ABI bool is_directory() const { return __get_ft() == file_type::directory; }
112 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_directory() const { return __get_ft() == file_type::directory; }
115113
116 _LIBCPP_HIDE_FROM_ABI bool is_directory(error_code& __ec) const noexcept {
114 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_directory(error_code& __ec) const noexcept {
117115 return __get_ft(&__ec) == file_type::directory;
118116 }
119117
120 _LIBCPP_HIDE_FROM_ABI bool is_fifo() const { return __get_ft() == file_type::fifo; }
118 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_fifo() const { return __get_ft() == file_type::fifo; }
121119
122 _LIBCPP_HIDE_FROM_ABI bool is_fifo(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::fifo; }
120 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_fifo(error_code& __ec) const noexcept {
121 return __get_ft(&__ec) == file_type::fifo;
122 }
123123
124 _LIBCPP_HIDE_FROM_ABI bool is_other() const { return filesystem::is_other(file_status{__get_ft()}); }
124 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_other() const { return filesystem::is_other(file_status{__get_ft()}); }
125125
126 _LIBCPP_HIDE_FROM_ABI bool is_other(error_code& __ec) const noexcept {
126 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_other(error_code& __ec) const noexcept {
127127 return filesystem::is_other(file_status{__get_ft(&__ec)});
128128 }
129129
130 _LIBCPP_HIDE_FROM_ABI bool is_regular_file() const { return __get_ft() == file_type::regular; }
130 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_regular_file() const { return __get_ft() == file_type::regular; }
131131
132 _LIBCPP_HIDE_FROM_ABI bool is_regular_file(error_code& __ec) const noexcept {
132 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_regular_file(error_code& __ec) const noexcept {
133133 return __get_ft(&__ec) == file_type::regular;
134134 }
135135
136 _LIBCPP_HIDE_FROM_ABI bool is_socket() const { return __get_ft() == file_type::socket; }
136 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_socket() const { return __get_ft() == file_type::socket; }
137137
138 _LIBCPP_HIDE_FROM_ABI bool is_socket(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::socket; }
138 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_socket(error_code& __ec) const noexcept {
139 return __get_ft(&__ec) == file_type::socket;
140 }
139141
140 _LIBCPP_HIDE_FROM_ABI bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
142 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
141143
142 _LIBCPP_HIDE_FROM_ABI bool is_symlink(error_code& __ec) const noexcept {
144 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_symlink(error_code& __ec) const noexcept {
143145 return __get_sym_ft(&__ec) == file_type::symlink;
144146 }
145 _LIBCPP_HIDE_FROM_ABI uintmax_t file_size() const { return __get_size(); }
147 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI uintmax_t file_size() const { return __get_size(); }
146148
147 _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(error_code& __ec) const noexcept { return __get_size(&__ec); }
149 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(error_code& __ec) const noexcept { return __get_size(&__ec); }
148150
149 _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count() const { return __get_nlink(); }
151 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count() const { return __get_nlink(); }
150152
151 _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(error_code& __ec) const noexcept { return __get_nlink(&__ec); }
153 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(error_code& __ec) const noexcept {
154 return __get_nlink(&__ec);
155 }
152156
153 _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time() const { return __get_write_time(); }
157 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time() const { return __get_write_time(); }
154158
155 _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(error_code& __ec) const noexcept {
159 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(error_code& __ec) const noexcept {
156160 return __get_write_time(&__ec);
157161 }
158162
159 _LIBCPP_HIDE_FROM_ABI file_status status() const { return __get_status(); }
163 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_status status() const { return __get_status(); }
160164
161 _LIBCPP_HIDE_FROM_ABI file_status status(error_code& __ec) const noexcept { return __get_status(&__ec); }
165 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_status status(error_code& __ec) const noexcept {
166 return __get_status(&__ec);
167 }
162168
163 _LIBCPP_HIDE_FROM_ABI file_status symlink_status() const { return __get_symlink_status(); }
169 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_status symlink_status() const { return __get_symlink_status(); }
164170
165 _LIBCPP_HIDE_FROM_ABI file_status symlink_status(error_code& __ec) const noexcept {
171 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_status symlink_status(error_code& __ec) const noexcept {
166172 return __get_symlink_status(&__ec);
167173 }
168174
......@@ -459,8 +465,6 @@ private:
459465 directory_entry __elem_;
460466};
461467
462_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
463
464468_LIBCPP_END_NAMESPACE_FILESYSTEM
465469
466470#endif // _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
lib/libcxx/include/__filesystem/directory_iterator.h+9-11
......@@ -34,8 +34,6 @@ _LIBCPP_PUSH_MACROS
3434
3535_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
3636
37_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
38
3937class _LIBCPP_HIDDEN __dir_stream;
4038class directory_iterator {
4139public:
......@@ -73,7 +71,7 @@ public:
7371
7472 _LIBCPP_HIDE_FROM_ABI ~directory_iterator() = default;
7573
76 _LIBCPP_HIDE_FROM_ABI const directory_entry& operator*() const {
74 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const directory_entry& operator*() const {
7775 // Note: this check duplicates a check in `__dereference()`.
7876 _LIBCPP_ASSERT_NON_NULL(__imp_, "The end iterator cannot be dereferenced");
7977 return __dereference();
......@@ -123,23 +121,23 @@ operator!=(const directory_iterator& __lhs, const directory_iterator& __rhs) noe
123121}
124122
125123// enable directory_iterator range-based for statements
126inline _LIBCPP_HIDE_FROM_ABI directory_iterator begin(directory_iterator __iter) noexcept { return __iter; }
127
128inline _LIBCPP_HIDE_FROM_ABI directory_iterator end(directory_iterator) noexcept { return directory_iterator(); }
124[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI directory_iterator begin(directory_iterator __iter) noexcept {
125 return __iter;
126}
129127
130_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
128[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI directory_iterator end(directory_iterator) noexcept {
129 return directory_iterator();
130}
131131
132132_LIBCPP_END_NAMESPACE_FILESYSTEM
133133
134134# if _LIBCPP_STD_VER >= 20
135135
136136template <>
137_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool
138 std::ranges::enable_borrowed_range<std::filesystem::directory_iterator> = true;
137inline constexpr bool std::ranges::enable_borrowed_range<std::filesystem::directory_iterator> = true;
139138
140139template <>
141_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool
142 std::ranges::enable_view<std::filesystem::directory_iterator> = true;
140inline constexpr bool std::ranges::enable_view<std::filesystem::directory_iterator> = true;
143141
144142# endif // _LIBCPP_STD_VER >= 20
145143
lib/libcxx/include/__filesystem/directory_options.h+7-4
......@@ -22,19 +22,22 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2222
2323enum class directory_options : unsigned char { none = 0, follow_directory_symlink = 1, skip_permission_denied = 2 };
2424
25_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator&(directory_options __lhs, directory_options __rhs) {
25[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr directory_options
26operator&(directory_options __lhs, directory_options __rhs) {
2627 return static_cast<directory_options>(static_cast<unsigned char>(__lhs) & static_cast<unsigned char>(__rhs));
2728}
2829
29_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator|(directory_options __lhs, directory_options __rhs) {
30[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr directory_options
31operator|(directory_options __lhs, directory_options __rhs) {
3032 return static_cast<directory_options>(static_cast<unsigned char>(__lhs) | static_cast<unsigned char>(__rhs));
3133}
3234
33_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator^(directory_options __lhs, directory_options __rhs) {
35[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr directory_options
36operator^(directory_options __lhs, directory_options __rhs) {
3437 return static_cast<directory_options>(static_cast<unsigned char>(__lhs) ^ static_cast<unsigned char>(__rhs));
3538}
3639
37_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator~(directory_options __lhs) {
40[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator~(directory_options __lhs) {
3841 return static_cast<directory_options>(~static_cast<unsigned char>(__lhs));
3942}
4043
lib/libcxx/include/__filesystem/file_status.h+3-3
......@@ -22,7 +22,7 @@
2222
2323_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2424
25class _LIBCPP_EXPORTED_FROM_ABI file_status {
25class file_status {
2626public:
2727 // constructors
2828 _LIBCPP_HIDE_FROM_ABI file_status() noexcept : file_status(file_type::none) {}
......@@ -38,9 +38,9 @@ public:
3838 _LIBCPP_HIDE_FROM_ABI file_status& operator=(file_status&&) noexcept = default;
3939
4040 // observers
41 _LIBCPP_HIDE_FROM_ABI file_type type() const noexcept { return __ft_; }
41 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_type type() const noexcept { return __ft_; }
4242
43 _LIBCPP_HIDE_FROM_ABI perms permissions() const noexcept { return __prms_; }
43 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI perms permissions() const noexcept { return __prms_; }
4444
4545 // modifiers
4646 _LIBCPP_HIDE_FROM_ABI void type(file_type __ft) noexcept { __ft_ = __ft; }
lib/libcxx/include/__filesystem/filesystem_error.h+9-10
......@@ -27,7 +27,7 @@
2727
2828_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2929
30class _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_EXPORTED_FROM_ABI filesystem_error : public system_error {
30class _LIBCPP_EXPORTED_FROM_ABI filesystem_error : public system_error {
3131public:
3232 _LIBCPP_HIDE_FROM_ABI filesystem_error(const string& __what, error_code __ec)
3333 : system_error(__ec, __what), __storage_(make_shared<_Storage>(path(), path())) {
......@@ -44,15 +44,16 @@ public:
4444 __create_what(2);
4545 }
4646
47 _LIBCPP_HIDE_FROM_ABI const path& path1() const noexcept { return __storage_->__p1_; }
47 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const path& path1() const noexcept { return __storage_->__p1_; }
4848
49 _LIBCPP_HIDE_FROM_ABI const path& path2() const noexcept { return __storage_->__p2_; }
49 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const path& path2() const noexcept { return __storage_->__p2_; }
5050
51 _LIBCPP_HIDE_FROM_ABI filesystem_error(const filesystem_error&) = default;
51 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI filesystem_error(const filesystem_error&) = default;
5252 ~filesystem_error() override; // key function
5353
54 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
55 const char* what() const noexcept override { return __storage_->__what_.c_str(); }
54 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI_VIRTUAL const char* what() const noexcept override {
55 return __storage_->__what_.c_str();
56 }
5657
5758 void __create_what(int __num_paths);
5859
......@@ -69,14 +70,12 @@ private:
6970
7071# if _LIBCPP_HAS_EXCEPTIONS
7172template <class... _Args>
72[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY void
73__throw_filesystem_error(_Args&&... __args) {
73[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_filesystem_error(_Args&&... __args) {
7474 throw filesystem_error(std::forward<_Args>(__args)...);
7575}
7676# else
7777template <class... _Args>
78[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY void
79__throw_filesystem_error(_Args&&...) {
78[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_filesystem_error(_Args&&...) {
8079 _LIBCPP_VERBOSE_ABORT("filesystem_error was thrown in -fno-exceptions mode");
8180}
8281# endif
lib/libcxx/include/__filesystem/operations.h+97-66
......@@ -31,8 +31,6 @@
3131
3232_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
3333
34_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
35
3634_LIBCPP_EXPORTED_FROM_ABI path __absolute(const path&, error_code* __ec = nullptr);
3735_LIBCPP_EXPORTED_FROM_ABI path __canonical(const path&, error_code* __ec = nullptr);
3836_LIBCPP_EXPORTED_FROM_ABI bool
......@@ -70,10 +68,14 @@ _LIBCPP_EXPORTED_FROM_ABI bool __fs_is_empty(const path& __p, error_code* __ec =
7068_LIBCPP_EXPORTED_FROM_ABI void __permissions(const path&, perms, perm_options, error_code* = nullptr);
7169_LIBCPP_EXPORTED_FROM_ABI space_info __space(const path&, error_code* __ec = nullptr);
7270
73inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p) { return __absolute(__p); }
74inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p, error_code& __ec) { return __absolute(__p, &__ec); }
75inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p) { return __canonical(__p); }
76inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p, error_code& __ec) { return __canonical(__p, &__ec); }
71[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p) { return __absolute(__p); }
72[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p, error_code& __ec) {
73 return __absolute(__p, &__ec);
74}
75[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p) { return __canonical(__p); }
76[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p, error_code& __ec) {
77 return __canonical(__p, &__ec);
78}
7779inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to) {
7880 return __copy_file(__from, __to, copy_options::none);
7981}
......@@ -137,85 +139,112 @@ inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const pat
137139inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link, error_code& __ec) noexcept {
138140 return __create_symlink(__target, __link, &__ec);
139141}
140inline _LIBCPP_HIDE_FROM_ABI path current_path() { return __current_path(); }
141inline _LIBCPP_HIDE_FROM_ABI path current_path(error_code& __ec) { return __current_path(&__ec); }
142[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path current_path() { return __current_path(); }
143[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path current_path(error_code& __ec) { return __current_path(&__ec); }
142144inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p) { __current_path(__p); }
143145inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p, error_code& __ec) noexcept {
144146 __current_path(__p, &__ec);
145147}
146inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2) { return __equivalent(__p1, __p2); }
147inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept {
148[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2) {
149 return __equivalent(__p1, __p2);
150}
151[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool
152equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept {
148153 return __equivalent(__p1, __p2, &__ec);
149154}
150inline _LIBCPP_HIDE_FROM_ABI bool status_known(file_status __s) noexcept { return __s.type() != file_type::none; }
151inline _LIBCPP_HIDE_FROM_ABI bool exists(file_status __s) noexcept {
155[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool status_known(file_status __s) noexcept {
156 return __s.type() != file_type::none;
157}
158[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool exists(file_status __s) noexcept {
152159 return status_known(__s) && __s.type() != file_type::not_found;
153160}
154inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p) { return exists(__status(__p)); }
161[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p) { return exists(__status(__p)); }
155162
156inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p, error_code& __ec) noexcept {
163[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p, error_code& __ec) noexcept {
157164 auto __s = __status(__p, &__ec);
158165 if (status_known(__s))
159166 __ec.clear();
160167 return exists(__s);
161168}
162169
163inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p) { return __file_size(__p); }
164inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p, error_code& __ec) noexcept {
170[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p) { return __file_size(__p); }
171[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p, error_code& __ec) noexcept {
165172 return __file_size(__p, &__ec);
166173}
167inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p) { return __hard_link_count(__p); }
168inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept {
174[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p) { return __hard_link_count(__p); }
175[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept {
169176 return __hard_link_count(__p, &__ec);
170177}
171inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(file_status __s) noexcept { return __s.type() == file_type::block; }
172inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p) { return is_block_file(__status(__p)); }
173inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p, error_code& __ec) noexcept {
178[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(file_status __s) noexcept {
179 return __s.type() == file_type::block;
180}
181[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p) { return is_block_file(__status(__p)); }
182[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p, error_code& __ec) noexcept {
174183 return is_block_file(__status(__p, &__ec));
175184}
176inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(file_status __s) noexcept {
185[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(file_status __s) noexcept {
177186 return __s.type() == file_type::character;
178187}
179inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p) { return is_character_file(__status(__p)); }
180inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p, error_code& __ec) noexcept {
188[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p) {
189 return is_character_file(__status(__p));
190}
191[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p, error_code& __ec) noexcept {
181192 return is_character_file(__status(__p, &__ec));
182193}
183inline _LIBCPP_HIDE_FROM_ABI bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; }
184inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p) { return is_directory(__status(__p)); }
185inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p, error_code& __ec) noexcept {
194[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_directory(file_status __s) noexcept {
195 return __s.type() == file_type::directory;
196}
197[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p) { return is_directory(__status(__p)); }
198[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p, error_code& __ec) noexcept {
186199 return is_directory(__status(__p, &__ec));
187200}
188inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p) { return __fs_is_empty(__p); }
189inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p, error_code& __ec) { return __fs_is_empty(__p, &__ec); }
190inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; }
191inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p) { return is_fifo(__status(__p)); }
192inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p, error_code& __ec) noexcept {
201[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p) { return __fs_is_empty(__p); }
202[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p, error_code& __ec) {
203 return __fs_is_empty(__p, &__ec);
204}
205[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(file_status __s) noexcept {
206 return __s.type() == file_type::fifo;
207}
208[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p) { return is_fifo(__status(__p)); }
209[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p, error_code& __ec) noexcept {
193210 return is_fifo(__status(__p, &__ec));
194211}
195inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(file_status __s) noexcept { return __s.type() == file_type::regular; }
196inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p) { return is_regular_file(__status(__p)); }
197inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p, error_code& __ec) noexcept {
212[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(file_status __s) noexcept {
213 return __s.type() == file_type::regular;
214}
215[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p) {
216 return is_regular_file(__status(__p));
217}
218[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p, error_code& __ec) noexcept {
198219 return is_regular_file(__status(__p, &__ec));
199220}
200inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(file_status __s) noexcept { return __s.type() == file_type::symlink; }
201inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p) { return is_symlink(__symlink_status(__p)); }
202inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p, error_code& __ec) noexcept {
221[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(file_status __s) noexcept {
222 return __s.type() == file_type::symlink;
223}
224[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p) {
225 return is_symlink(__symlink_status(__p));
226}
227[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p, error_code& __ec) noexcept {
203228 return is_symlink(__symlink_status(__p, &__ec));
204229}
205inline _LIBCPP_HIDE_FROM_ABI bool is_other(file_status __s) noexcept {
230[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_other(file_status __s) noexcept {
206231 return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s);
207232}
208inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p) { return is_other(__status(__p)); }
209inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p, error_code& __ec) noexcept {
233[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p) { return is_other(__status(__p)); }
234[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p, error_code& __ec) noexcept {
210235 return is_other(__status(__p, &__ec));
211236}
212inline _LIBCPP_HIDE_FROM_ABI bool is_socket(file_status __s) noexcept { return __s.type() == file_type::socket; }
213inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p) { return is_socket(__status(__p)); }
214inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p, error_code& __ec) noexcept {
237[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_socket(file_status __s) noexcept {
238 return __s.type() == file_type::socket;
239}
240[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p) { return is_socket(__status(__p)); }
241[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p, error_code& __ec) noexcept {
215242 return is_socket(__status(__p, &__ec));
216243}
217inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p) { return __last_write_time(__p); }
218inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p, error_code& __ec) noexcept {
244[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p) {
245 return __last_write_time(__p);
246}
247[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p, error_code& __ec) noexcept {
219248 return __last_write_time(__p, &__ec);
220249}
221250inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t) { __last_write_time(__p, __t); }
......@@ -233,7 +262,7 @@ inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, per
233262 __permissions(__p, __prms, __opts, &__ec);
234263}
235264
236inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base, error_code& __ec) {
265[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base, error_code& __ec) {
237266 path __tmp = __weakly_canonical(__p, &__ec);
238267 if (__ec)
239268 return {};
......@@ -243,16 +272,18 @@ inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base,
243272 return __tmp.lexically_proximate(__tmp_base);
244273}
245274
246inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, error_code& __ec) {
275[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, error_code& __ec) {
247276 return proximate(__p, current_path(), __ec);
248277}
249inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base = current_path()) {
278[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base = current_path()) {
250279 return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base));
251280}
252inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p) { return __read_symlink(__p); }
253inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p, error_code& __ec) { return __read_symlink(__p, &__ec); }
281[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p) { return __read_symlink(__p); }
282[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p, error_code& __ec) {
283 return __read_symlink(__p, &__ec);
284}
254285
255inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base, error_code& __ec) {
286[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base, error_code& __ec) {
256287 path __tmp = __weakly_canonical(__p, &__ec);
257288 if (__ec)
258289 return path();
......@@ -262,10 +293,10 @@ inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base,
262293 return __tmp.lexically_relative(__tmpbase);
263294}
264295
265inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, error_code& __ec) {
296[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, error_code& __ec) {
266297 return relative(__p, current_path(), __ec);
267298}
268inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base = current_path()) {
299[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base = current_path()) {
269300 return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
270301}
271302inline _LIBCPP_HIDE_FROM_ABI uintmax_t remove_all(const path& __p) { return __remove_all(__p); }
......@@ -282,27 +313,27 @@ inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns) {
282313inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept {
283314 return __resize_file(__p, __ns, &__ec);
284315}
285inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p) { return __space(__p); }
286inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p, error_code& __ec) noexcept {
316[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p) { return __space(__p); }
317[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p, error_code& __ec) noexcept {
287318 return __space(__p, &__ec);
288319}
289inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p) { return __status(__p); }
290inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p, error_code& __ec) noexcept {
320[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p) { return __status(__p); }
321[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p, error_code& __ec) noexcept {
291322 return __status(__p, &__ec);
292323}
293inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p) { return __symlink_status(__p); }
294inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p, error_code& __ec) noexcept {
324[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p) { return __symlink_status(__p); }
325[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p, error_code& __ec) noexcept {
295326 return __symlink_status(__p, &__ec);
296327}
297inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path() { return __temp_directory_path(); }
298inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path(error_code& __ec) { return __temp_directory_path(&__ec); }
299inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p) { return __weakly_canonical(__p); }
300inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p, error_code& __ec) {
328[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path() { return __temp_directory_path(); }
329[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path(error_code& __ec) {
330 return __temp_directory_path(&__ec);
331}
332[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p) { return __weakly_canonical(__p); }
333[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p, error_code& __ec) {
301334 return __weakly_canonical(__p, &__ec);
302335}
303336
304_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
305
306337_LIBCPP_END_NAMESPACE_FILESYSTEM
307338
308339#endif // _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_FILESYSTEM
lib/libcxx/include/__filesystem/path.h+68-64
......@@ -42,8 +42,6 @@ _LIBCPP_PUSH_MACROS
4242
4343_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
4444
45_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
46
4745template <class _Tp>
4846struct __can_convert_char {
4947 static const bool value = false;
......@@ -326,6 +324,7 @@ struct _PathCVT<char> {
326324 }
327325};
328326
327# if _LIBCPP_HAS_LOCALIZATION
329328template <class _ECharT>
330329struct _PathExport {
331330 typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
......@@ -366,7 +365,7 @@ struct _PathExport<char16_t> {
366365 }
367366};
368367
369# if _LIBCPP_HAS_CHAR8_T
368# if _LIBCPP_HAS_CHAR8_T
370369template <>
371370struct _PathExport<char8_t> {
372371 typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
......@@ -376,8 +375,9 @@ struct _PathExport<char8_t> {
376375 _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size());
377376 }
378377};
379# endif // _LIBCPP_HAS_CHAR8_T
380# endif /* _LIBCPP_WIN32API */
378# endif // _LIBCPP_HAS_CHAR8_T
379# endif // _LIBCPP_HAS_LOCALIZATION
380# endif // _LIBCPP_WIN32API
381381
382382class _LIBCPP_EXPORTED_FROM_ABI path {
383383 template <class _SourceOrIter, class _Tp = path&>
......@@ -667,16 +667,16 @@ public:
667667 _LIBCPP_HIDE_FROM_ABI void __reserve(size_t __s) { __pn_.reserve(__s); }
668668
669669 // native format observers
670 _LIBCPP_HIDE_FROM_ABI const string_type& native() const noexcept { return __pn_; }
670 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const string_type& native() const noexcept { return __pn_; }
671671
672 _LIBCPP_HIDE_FROM_ABI const value_type* c_str() const noexcept { return __pn_.c_str(); }
672 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const value_type* c_str() const noexcept { return __pn_.c_str(); }
673673
674674 _LIBCPP_HIDE_FROM_ABI operator string_type() const { return __pn_; }
675675
676676# if defined(_LIBCPP_WIN32API)
677 _LIBCPP_HIDE_FROM_ABI std::wstring wstring() const { return __pn_; }
677 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::wstring wstring() const { return __pn_; }
678678
679 _LIBCPP_HIDE_FROM_ABI std::wstring generic_wstring() const {
679 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::wstring generic_wstring() const {
680680 std::wstring __s;
681681 __s.resize(__pn_.size());
682682 std::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/');
......@@ -685,6 +685,7 @@ public:
685685
686686# if _LIBCPP_HAS_LOCALIZATION
687687 template <class _ECharT, class _Traits = char_traits<_ECharT>, class _Allocator = allocator<_ECharT> >
688 [[nodiscard]]
688689 _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator> string(const _Allocator& __a = _Allocator()) const {
689690 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
690691 _Str __s(__a);
......@@ -693,8 +694,8 @@ public:
693694 return __s;
694695 }
695696
696 _LIBCPP_HIDE_FROM_ABI std::string string() const { return string<char>(); }
697 _LIBCPP_HIDE_FROM_ABI __u8_string u8string() const {
697 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::string string() const { return string<char>(); }
698 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __u8_string u8string() const {
698699 using _CVT = __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
699700 __u8_string __s;
700701 __s.reserve(__pn_.size());
......@@ -702,12 +703,12 @@ public:
702703 return __s;
703704 }
704705
705 _LIBCPP_HIDE_FROM_ABI std::u16string u16string() const { return string<char16_t>(); }
706 _LIBCPP_HIDE_FROM_ABI std::u32string u32string() const { return string<char32_t>(); }
706 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::u16string u16string() const { return string<char16_t>(); }
707 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::u32string u32string() const { return string<char32_t>(); }
707708
708709 // generic format observers
709710 template <class _ECharT, class _Traits = char_traits<_ECharT>, class _Allocator = allocator<_ECharT> >
710 _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator>
711 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator>
711712 generic_string(const _Allocator& __a = _Allocator()) const {
712713 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
713714 _Str __s = string<_ECharT, _Traits, _Allocator>(__a);
......@@ -718,10 +719,10 @@ public:
718719 return __s;
719720 }
720721
721 _LIBCPP_HIDE_FROM_ABI std::string generic_string() const { return generic_string<char>(); }
722 _LIBCPP_HIDE_FROM_ABI std::u16string generic_u16string() const { return generic_string<char16_t>(); }
723 _LIBCPP_HIDE_FROM_ABI std::u32string generic_u32string() const { return generic_string<char32_t>(); }
724 _LIBCPP_HIDE_FROM_ABI __u8_string generic_u8string() const {
722 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::string generic_string() const { return generic_string<char>(); }
723 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::u16string generic_u16string() const { return generic_string<char16_t>(); }
724 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::u32string generic_u32string() const { return generic_string<char32_t>(); }
725 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __u8_string generic_u8string() const {
725726 __u8_string __s = u8string();
726727 std::replace(__s.begin(), __s.end(), '\\', '/');
727728 return __s;
......@@ -729,15 +730,18 @@ public:
729730# endif // _LIBCPP_HAS_LOCALIZATION
730731# else /* _LIBCPP_WIN32API */
731732
732 _LIBCPP_HIDE_FROM_ABI std::string string() const { return __pn_; }
733 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::string string() const { return __pn_; }
733734# if _LIBCPP_HAS_CHAR8_T
734 _LIBCPP_HIDE_FROM_ABI std::u8string u8string() const { return std::u8string(__pn_.begin(), __pn_.end()); }
735 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::u8string u8string() const {
736 return std::u8string(__pn_.begin(), __pn_.end());
737 }
735738# else
736 _LIBCPP_HIDE_FROM_ABI std::string u8string() const { return __pn_; }
739 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::string u8string() const { return __pn_; }
737740# endif
738741
739742# if _LIBCPP_HAS_LOCALIZATION
740743 template <class _ECharT, class _Traits = char_traits<_ECharT>, class _Allocator = allocator<_ECharT> >
744 [[nodiscard]]
741745 _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator> string(const _Allocator& __a = _Allocator()) const {
742746 using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>;
743747 using _Str = basic_string<_ECharT, _Traits, _Allocator>;
......@@ -748,32 +752,34 @@ public:
748752 }
749753
750754# if _LIBCPP_HAS_WIDE_CHARACTERS
751 _LIBCPP_HIDE_FROM_ABI std::wstring wstring() const { return string<wchar_t>(); }
755 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::wstring wstring() const { return string<wchar_t>(); }
752756# endif
753 _LIBCPP_HIDE_FROM_ABI std::u16string u16string() const { return string<char16_t>(); }
754 _LIBCPP_HIDE_FROM_ABI std::u32string u32string() const { return string<char32_t>(); }
757 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::u16string u16string() const { return string<char16_t>(); }
758 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::u32string u32string() const { return string<char32_t>(); }
755759# endif // _LIBCPP_HAS_LOCALIZATION
756760
757761 // generic format observers
758 _LIBCPP_HIDE_FROM_ABI std::string generic_string() const { return __pn_; }
762 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::string generic_string() const { return __pn_; }
759763# if _LIBCPP_HAS_CHAR8_T
760 _LIBCPP_HIDE_FROM_ABI std::u8string generic_u8string() const { return std::u8string(__pn_.begin(), __pn_.end()); }
764 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::u8string generic_u8string() const {
765 return std::u8string(__pn_.begin(), __pn_.end());
766 }
761767# else
762 _LIBCPP_HIDE_FROM_ABI std::string generic_u8string() const { return __pn_; }
768 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::string generic_u8string() const { return __pn_; }
763769# endif
764770
765771# if _LIBCPP_HAS_LOCALIZATION
766772 template <class _ECharT, class _Traits = char_traits<_ECharT>, class _Allocator = allocator<_ECharT> >
767 _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator>
773 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator>
768774 generic_string(const _Allocator& __a = _Allocator()) const {
769775 return string<_ECharT, _Traits, _Allocator>(__a);
770776 }
771777
772778# if _LIBCPP_HAS_WIDE_CHARACTERS
773 _LIBCPP_HIDE_FROM_ABI std::wstring generic_wstring() const { return string<wchar_t>(); }
779 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::wstring generic_wstring() const { return string<wchar_t>(); }
774780# endif
775 _LIBCPP_HIDE_FROM_ABI std::u16string generic_u16string() const { return string<char16_t>(); }
776 _LIBCPP_HIDE_FROM_ABI std::u32string generic_u32string() const { return string<char32_t>(); }
781 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::u16string generic_u16string() const { return string<char16_t>(); }
782 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::u32string generic_u32string() const { return string<char32_t>(); }
777783# endif // _LIBCPP_HAS_LOCALIZATION
778784# endif /* !_LIBCPP_WIN32API */
779785
......@@ -790,40 +796,40 @@ private:
790796
791797public:
792798 // compare
793 _LIBCPP_HIDE_FROM_ABI int compare(const path& __p) const noexcept { return __compare(__p.__pn_); }
794 _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const { return __compare(__s); }
795 _LIBCPP_HIDE_FROM_ABI int compare(__string_view __s) const { return __compare(__s); }
796 _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { return __compare(__s); }
799 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI int compare(const path& __p) const noexcept { return __compare(__p.__pn_); }
800 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const { return __compare(__s); }
801 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI int compare(__string_view __s) const { return __compare(__s); }
802 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { return __compare(__s); }
797803
798804 // decomposition
799 _LIBCPP_HIDE_FROM_ABI path root_name() const { return string_type(__root_name()); }
800 _LIBCPP_HIDE_FROM_ABI path root_directory() const { return string_type(__root_directory()); }
801 _LIBCPP_HIDE_FROM_ABI path root_path() const {
805 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI path root_name() const { return string_type(__root_name()); }
806 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI path root_directory() const { return string_type(__root_directory()); }
807 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI path root_path() const {
802808# if defined(_LIBCPP_WIN32API)
803809 return string_type(__root_path_raw());
804810# else
805811 return root_name().append(string_type(__root_directory()));
806812# endif
807813 }
808 _LIBCPP_HIDE_FROM_ABI path relative_path() const { return string_type(__relative_path()); }
809 _LIBCPP_HIDE_FROM_ABI path parent_path() const { return string_type(__parent_path()); }
810 _LIBCPP_HIDE_FROM_ABI path filename() const { return string_type(__filename()); }
811 _LIBCPP_HIDE_FROM_ABI path stem() const { return string_type(__stem()); }
812 _LIBCPP_HIDE_FROM_ABI path extension() const { return string_type(__extension()); }
814 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI path relative_path() const { return string_type(__relative_path()); }
815 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI path parent_path() const { return string_type(__parent_path()); }
816 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI path filename() const { return string_type(__filename()); }
817 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI path stem() const { return string_type(__stem()); }
818 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI path extension() const { return string_type(__extension()); }
813819
814820 // query
815821 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __pn_.empty(); }
816822
817 _LIBCPP_HIDE_FROM_ABI bool has_root_name() const { return !__root_name().empty(); }
818 _LIBCPP_HIDE_FROM_ABI bool has_root_directory() const { return !__root_directory().empty(); }
819 _LIBCPP_HIDE_FROM_ABI bool has_root_path() const { return !__root_path_raw().empty(); }
820 _LIBCPP_HIDE_FROM_ABI bool has_relative_path() const { return !__relative_path().empty(); }
821 _LIBCPP_HIDE_FROM_ABI bool has_parent_path() const { return !__parent_path().empty(); }
822 _LIBCPP_HIDE_FROM_ABI bool has_filename() const { return !__filename().empty(); }
823 _LIBCPP_HIDE_FROM_ABI bool has_stem() const { return !__stem().empty(); }
824 _LIBCPP_HIDE_FROM_ABI bool has_extension() const { return !__extension().empty(); }
823 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool has_root_name() const { return !__root_name().empty(); }
824 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool has_root_directory() const { return !__root_directory().empty(); }
825 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool has_root_path() const { return !__root_path_raw().empty(); }
826 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool has_relative_path() const { return !__relative_path().empty(); }
827 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool has_parent_path() const { return !__parent_path().empty(); }
828 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool has_filename() const { return !__filename().empty(); }
829 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool has_stem() const { return !__stem().empty(); }
830 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool has_extension() const { return !__extension().empty(); }
825831
826 _LIBCPP_HIDE_FROM_ABI bool is_absolute() const {
832 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_absolute() const {
827833# if defined(_LIBCPP_WIN32API)
828834 __string_view __root_name_str = __root_name();
829835 __string_view __root_dir = __root_directory();
......@@ -847,13 +853,13 @@ public:
847853 return has_root_directory();
848854# endif
849855 }
850 _LIBCPP_HIDE_FROM_ABI bool is_relative() const { return !is_absolute(); }
856 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_relative() const { return !is_absolute(); }
851857
852858 // relative paths
853 path lexically_normal() const;
854 path lexically_relative(const path& __base) const;
859 [[nodiscard]] path lexically_normal() const;
860 [[nodiscard]] path lexically_relative(const path& __base) const;
855861
856 _LIBCPP_HIDE_FROM_ABI path lexically_proximate(const path& __base) const {
862 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI path lexically_proximate(const path& __base) const {
857863 path __result = this->lexically_relative(__base);
858864 if (__result.native().empty())
859865 return *this;
......@@ -861,11 +867,11 @@ public:
861867 }
862868
863869 // iterators
864 class _LIBCPP_EXPORTED_FROM_ABI iterator;
870 class iterator;
865871 typedef iterator const_iterator;
866872
867 iterator begin() const;
868 iterator end() const;
873 [[nodiscard]] iterator begin() const;
874 [[nodiscard]] iterator end() const;
869875
870876# if _LIBCPP_HAS_LOCALIZATION
871877 template <
......@@ -908,17 +914,15 @@ private:
908914
909915inline _LIBCPP_HIDE_FROM_ABI void swap(path& __lhs, path& __rhs) noexcept { __lhs.swap(__rhs); }
910916
911_LIBCPP_EXPORTED_FROM_ABI size_t hash_value(const path& __p) noexcept;
912
913_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
917[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI size_t hash_value(const path& __p) noexcept;
914918
915919_LIBCPP_END_NAMESPACE_FILESYSTEM
916920
917921_LIBCPP_BEGIN_NAMESPACE_STD
918922
919923template <>
920struct _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY hash<filesystem::path> : __unary_function<filesystem::path, size_t> {
921 _LIBCPP_HIDE_FROM_ABI size_t operator()(filesystem::path const& __p) const noexcept {
924struct hash<filesystem::path> : __unary_function<filesystem::path, size_t> {
925 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(filesystem::path const& __p) const noexcept {
922926 return filesystem::hash_value(__p);
923927 }
924928};
lib/libcxx/include/__filesystem/path_iterator.h+1-3
......@@ -52,7 +52,7 @@ public:
5252
5353 _LIBCPP_HIDE_FROM_ABI iterator& operator=(const iterator&) = default;
5454
55 _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __stashed_elem_; }
55 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __stashed_elem_; }
5656
5757 _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return &__stashed_elem_; }
5858
......@@ -95,12 +95,10 @@ private:
9595 _ParserState __state_;
9696};
9797
98_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
9998inline _LIBCPP_HIDE_FROM_ABI bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) {
10099 return __lhs.__path_ptr_ == __rhs.__path_ptr_ && __lhs.__entry_.data() == __rhs.__entry_.data();
101100}
102101
103_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
104102inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) {
105103 return !(__lhs == __rhs);
106104}
lib/libcxx/include/__filesystem/perm_options.h+4-4
......@@ -22,19 +22,19 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2222
2323enum class perm_options : unsigned char { replace = 1, add = 2, remove = 4, nofollow = 8 };
2424
25_LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator&(perm_options __lhs, perm_options __rhs) {
25[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator&(perm_options __lhs, perm_options __rhs) {
2626 return static_cast<perm_options>(static_cast<unsigned>(__lhs) & static_cast<unsigned>(__rhs));
2727}
2828
29_LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator|(perm_options __lhs, perm_options __rhs) {
29[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator|(perm_options __lhs, perm_options __rhs) {
3030 return static_cast<perm_options>(static_cast<unsigned>(__lhs) | static_cast<unsigned>(__rhs));
3131}
3232
33_LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator^(perm_options __lhs, perm_options __rhs) {
33[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator^(perm_options __lhs, perm_options __rhs) {
3434 return static_cast<perm_options>(static_cast<unsigned>(__lhs) ^ static_cast<unsigned>(__rhs));
3535}
3636
37_LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator~(perm_options __lhs) {
37[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator~(perm_options __lhs) {
3838 return static_cast<perm_options>(~static_cast<unsigned>(__lhs));
3939}
4040
lib/libcxx/include/__filesystem/perms.h+4-4
......@@ -51,19 +51,19 @@ enum class perms : unsigned {
5151 unknown = 0xFFFF,
5252};
5353
54_LIBCPP_HIDE_FROM_ABI inline constexpr perms operator&(perms __lhs, perms __rhs) {
54[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr perms operator&(perms __lhs, perms __rhs) {
5555 return static_cast<perms>(static_cast<unsigned>(__lhs) & static_cast<unsigned>(__rhs));
5656}
5757
58_LIBCPP_HIDE_FROM_ABI inline constexpr perms operator|(perms __lhs, perms __rhs) {
58[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr perms operator|(perms __lhs, perms __rhs) {
5959 return static_cast<perms>(static_cast<unsigned>(__lhs) | static_cast<unsigned>(__rhs));
6060}
6161
62_LIBCPP_HIDE_FROM_ABI inline constexpr perms operator^(perms __lhs, perms __rhs) {
62[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr perms operator^(perms __lhs, perms __rhs) {
6363 return static_cast<perms>(static_cast<unsigned>(__lhs) ^ static_cast<unsigned>(__rhs));
6464}
6565
66_LIBCPP_HIDE_FROM_ABI inline constexpr perms operator~(perms __lhs) {
66[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr perms operator~(perms __lhs) {
6767 return static_cast<perms>(~static_cast<unsigned>(__lhs));
6868}
6969
lib/libcxx/include/__filesystem/recursive_directory_iterator.h+9-14
......@@ -33,8 +33,6 @@ _LIBCPP_PUSH_MACROS
3333
3434_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
3535
36_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
37
3836class recursive_directory_iterator {
3937public:
4038 using value_type = directory_entry;
......@@ -73,7 +71,7 @@ public:
7371
7472 _LIBCPP_HIDE_FROM_ABI ~recursive_directory_iterator() = default;
7573
76 _LIBCPP_HIDE_FROM_ABI const directory_entry& operator*() const { return __dereference(); }
74 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const directory_entry& operator*() const { return __dereference(); }
7775
7876 _LIBCPP_HIDE_FROM_ABI const directory_entry* operator->() const { return &__dereference(); }
7977
......@@ -87,14 +85,14 @@ public:
8785
8886 _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
8987
90 _LIBCPP_EXPORTED_FROM_ABI directory_options options() const;
91 _LIBCPP_EXPORTED_FROM_ABI int depth() const;
88 [[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI directory_options options() const;
89 [[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI int depth() const;
9290
9391 _LIBCPP_HIDE_FROM_ABI void pop() { __pop(); }
9492
9593 _LIBCPP_HIDE_FROM_ABI void pop(error_code& __ec) { __pop(&__ec); }
9694
97 _LIBCPP_HIDE_FROM_ABI bool recursion_pending() const { return __rec_; }
95 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool recursion_pending() const { return __rec_; }
9896
9997 _LIBCPP_HIDE_FROM_ABI void disable_recursion_pending() { __rec_ = false; }
10098
......@@ -132,27 +130,24 @@ operator!=(const recursive_directory_iterator& __lhs, const recursive_directory_
132130 return !(__lhs == __rhs);
133131}
134132// enable recursive_directory_iterator range-based for statements
135inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator begin(recursive_directory_iterator __iter) noexcept {
133[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator
134begin(recursive_directory_iterator __iter) noexcept {
136135 return __iter;
137136}
138137
139inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator end(recursive_directory_iterator) noexcept {
138[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator end(recursive_directory_iterator) noexcept {
140139 return recursive_directory_iterator();
141140}
142141
143_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
144
145142_LIBCPP_END_NAMESPACE_FILESYSTEM
146143
147144# if _LIBCPP_STD_VER >= 20
148145
149146template <>
150_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool
151 std::ranges::enable_borrowed_range<std::filesystem::recursive_directory_iterator> = true;
147inline constexpr bool std::ranges::enable_borrowed_range<std::filesystem::recursive_directory_iterator> = true;
152148
153149template <>
154_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool
155 std::ranges::enable_view<std::filesystem::recursive_directory_iterator> = true;
150inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_directory_iterator> = true;
156151
157152# endif // _LIBCPP_STD_VER >= 20
158153
lib/libcxx/include/__filesystem/space_info.h+1-1
......@@ -21,7 +21,7 @@
2121
2222_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2323
24struct _LIBCPP_EXPORTED_FROM_ABI space_info {
24struct space_info {
2525 uintmax_t capacity;
2626 uintmax_t free;
2727 uintmax_t available;
lib/libcxx/include/__filesystem/u8path.h+12-14
......@@ -24,32 +24,32 @@
2424
2525_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2626
27_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
28
27# if !defined(_LIBCPP_WIN32API) || _LIBCPP_HAS_LOCALIZATION
2928template <class _InputIt, __enable_if_t<__is_pathable<_InputIt>::value, int> = 0>
30_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _InputIt __l) {
29[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _InputIt __l) {
3130 static_assert(
32# if _LIBCPP_HAS_CHAR8_T
31# if _LIBCPP_HAS_CHAR8_T
3332 is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
34# endif
33# endif
3534 is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
3635 "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
3736 " or 'char8_t'");
38# if defined(_LIBCPP_WIN32API)
37# if defined(_LIBCPP_WIN32API)
3938 string __tmp(__f, __l);
4039 using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>;
4140 std::wstring __w;
4241 __w.reserve(__tmp.size());
4342 _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
4443 return path(__w);
45# else
44# else
4645 return path(__f, __l);
47# endif /* !_LIBCPP_WIN32API */
46# endif // defined(_LIBCPP_WIN32API)
4847}
48# endif // !defined(_LIBCPP_WIN32API) || _LIBCPP_HAS_LOCALIZATION
4949
50# if defined(_LIBCPP_WIN32API)
50# if defined(_LIBCPP_WIN32API) && _LIBCPP_HAS_LOCALIZATION
5151template <class _InputIt, __enable_if_t<__is_pathable<_InputIt>::value, int> = 0>
52_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _NullSentinel) {
52[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _NullSentinel) {
5353 static_assert(
5454# if _LIBCPP_HAS_CHAR8_T
5555 is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
......@@ -67,10 +67,10 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f,
6767 _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size());
6868 return path(__w);
6969}
70# endif /* _LIBCPP_WIN32API */
70# endif // defined(_LIBCPP_WIN32API) && _LIBCPP_HAS_LOCALIZATION
7171
7272template <class _Source, __enable_if_t<__is_pathable<_Source>::value, int> = 0>
73_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(const _Source& __s) {
73[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(const _Source& __s) {
7474 static_assert(
7575# if _LIBCPP_HAS_CHAR8_T
7676 is_same<typename __is_pathable<_Source>::__char_type, char8_t>::value ||
......@@ -86,8 +86,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(const _Source&
8686# endif
8787}
8888
89_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
90
9189_LIBCPP_END_NAMESPACE_FILESYSTEM
9290
9391#endif // _LIBCPP_STD_VER >= 17
lib/libcxx/include/__flat_map/flat_map.h+88-71
......@@ -29,7 +29,6 @@
2929#include <__flat_map/key_value_iterator.h>
3030#include <__flat_map/sorted_unique.h>
3131#include <__flat_map/utils.h>
32#include <__functional/invoke.h>
3332#include <__functional/is_transparent.h>
3433#include <__functional/operations.h>
3534#include <__fwd/memory.h>
......@@ -48,7 +47,7 @@
4847#include <__ranges/container_compatible_range.h>
4948#include <__ranges/drop_view.h>
5049#include <__ranges/from_range.h>
51#include <__ranges/ref_view.h>
50#include <__ranges/range_adaptor.h>
5251#include <__ranges/size.h>
5352#include <__ranges/subrange.h>
5453#include <__ranges/zip_view.h>
......@@ -410,41 +409,45 @@ public:
410409 }
411410
412411 // iterators
413 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
412 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
414413 return iterator(__containers_.keys.begin(), __containers_.values.begin());
415414 }
416415
417 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
416 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
418417 return const_iterator(__containers_.keys.begin(), __containers_.values.begin());
419418 }
420419
421 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
420 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
422421 return iterator(__containers_.keys.end(), __containers_.values.end());
423422 }
424423
425 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
424 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
426425 return const_iterator(__containers_.keys.end(), __containers_.values.end());
427426 }
428427
429 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
428 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
430429 return reverse_iterator(end());
431430 }
432 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
431 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
433432 return const_reverse_iterator(end());
434433 }
435 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
434 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
436435 return reverse_iterator(begin());
437436 }
438 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
437 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
439438 return const_reverse_iterator(begin());
440439 }
441440
442 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { return begin(); }
443 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { return end(); }
444 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
441 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept {
442 return begin();
443 }
444 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept {
445 return end();
446 }
447 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
445448 return const_reverse_iterator(end());
446449 }
447 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
450 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
448451 return const_reverse_iterator(begin());
449452 }
450453
......@@ -453,11 +456,11 @@ public:
453456 return __containers_.keys.empty();
454457 }
455458
456 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
459 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
457460 return __containers_.keys.size();
458461 }
459462
460 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
463 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
461464 return std::min<size_type>(__containers_.keys.max_size(), __containers_.values.max_size());
462465 }
463466
......@@ -481,7 +484,7 @@ public:
481484 return try_emplace(std::forward<_Kp>(__x)).first->second;
482485 }
483486
484 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const key_type& __x) {
487 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const key_type& __x) {
485488 auto __it = find(__x);
486489 if (__it == end()) {
487490 std::__throw_out_of_range("flat_map::at(const key_type&): Key does not exist");
......@@ -489,7 +492,7 @@ public:
489492 return __it->second;
490493 }
491494
492 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const key_type& __x) const {
495 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const key_type& __x) const {
493496 auto __it = find(__x);
494497 if (__it == end()) {
495498 std::__throw_out_of_range("flat_map::at(const key_type&) const: Key does not exist");
......@@ -499,7 +502,7 @@ public:
499502
500503 template <class _Kp>
501504 requires __is_compare_transparent
502 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const _Kp& __x) {
505 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const _Kp& __x) {
503506 auto __it = find(__x);
504507 if (__it == end()) {
505508 std::__throw_out_of_range("flat_map::at(const K&): Key does not exist");
......@@ -509,7 +512,7 @@ public:
509512
510513 template <class _Kp>
511514 requires __is_compare_transparent
512 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const _Kp& __x) const {
515 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const _Kp& __x) const {
513516 auto __it = find(__x);
514517 if (__it == end()) {
515518 std::__throw_out_of_range("flat_map::at(const K&) const: Key does not exist");
......@@ -589,6 +592,15 @@ public:
589592 __append_sort_merge_unique</*WasSorted = */ false>(ranges::begin(__range), ranges::end(__range));
590593 }
591594
595 template <_ContainerCompatibleRange<value_type> _Range>
596 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(sorted_unique_t, _Range&& __range) {
597 if constexpr (ranges::sized_range<_Range>) {
598 __reserve(ranges::size(__range));
599 }
600
601 __append_sort_merge_unique</*WasSorted = */ true>(ranges::begin(__range), ranges::end(__range));
602 }
603
592604 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(initializer_list<value_type> __il) {
593605 insert(__il.begin(), __il.end());
594606 }
......@@ -597,7 +609,7 @@ public:
597609 insert(sorted_unique, __il.begin(), __il.end());
598610 }
599611
600 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && {
612 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && {
601613 auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; });
602614 auto __ret = std::move(__containers_);
603615 return __ret;
......@@ -738,14 +750,17 @@ public:
738750 return iterator(std::move(__key_it), std::move(__mapped_it));
739751 }
740752
741 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_map& __y) noexcept {
742 // warning: The spec has unconditional noexcept, which means that
743 // if any of the following functions throw an exception,
744 // std::terminate will be called.
745 // This is discussed in P2767, which hasn't been voted on yet.
753 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
754 swap(flat_map& __y) noexcept(is_nothrow_swappable_v<key_container_type> &&
755 is_nothrow_swappable_v<mapped_container_type> && is_nothrow_swappable_v<key_compare>) {
756 auto __on_failure = std::__make_exception_guard([&]() noexcept {
757 clear() /* noexcept */;
758 __y.clear() /* noexcept */;
759 });
746760 ranges::swap(__compare_, __y.__compare_);
747761 ranges::swap(__containers_.keys, __y.__containers_.keys);
748762 ranges::swap(__containers_.values, __y.__containers_.values);
763 __on_failure.__complete();
749764 }
750765
751766 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept {
......@@ -754,116 +769,121 @@ public:
754769 }
755770
756771 // observers
757 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
758 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
772 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
773 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
759774 return value_compare(__compare_);
760775 }
761776
762 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept {
777 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept {
763778 return __containers_.keys;
764779 }
765 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type& values() const noexcept {
780 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type&
781 values() const noexcept {
766782 return __containers_.values;
767783 }
768784
769785 // map operations
770 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
786 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
771787 return __find_impl(*this, __x);
772788 }
773789
774 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
790 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
775791 return __find_impl(*this, __x);
776792 }
777793
778794 template <class _Kp>
779795 requires __is_compare_transparent
780 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
796 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
781797 return __find_impl(*this, __x);
782798 }
783799
784800 template <class _Kp>
785801 requires __is_compare_transparent
786 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
802 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
787803 return __find_impl(*this, __x);
788804 }
789805
790 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
806 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
791807 return contains(__x) ? 1 : 0;
792808 }
793809
794810 template <class _Kp>
795811 requires __is_compare_transparent
796 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
812 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
797813 return contains(__x) ? 1 : 0;
798814 }
799815
800 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
816 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
801817 return find(__x) != end();
802818 }
803819
804820 template <class _Kp>
805821 requires __is_compare_transparent
806 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
822 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
807823 return find(__x) != end();
808824 }
809825
810 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
826 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
811827 return __lower_bound<iterator>(*this, __x);
812828 }
813829
814 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const key_type& __x) const {
830 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
831 lower_bound(const key_type& __x) const {
815832 return __lower_bound<const_iterator>(*this, __x);
816833 }
817834
818835 template <class _Kp>
819836 requires __is_compare_transparent
820 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
837 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
821838 return __lower_bound<iterator>(*this, __x);
822839 }
823840
824841 template <class _Kp>
825842 requires __is_compare_transparent
826 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
843 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
827844 return __lower_bound<const_iterator>(*this, __x);
828845 }
829846
830 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
847 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
831848 return __upper_bound<iterator>(*this, __x);
832849 }
833850
834 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const key_type& __x) const {
851 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
852 upper_bound(const key_type& __x) const {
835853 return __upper_bound<const_iterator>(*this, __x);
836854 }
837855
838856 template <class _Kp>
839857 requires __is_compare_transparent
840 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
858 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
841859 return __upper_bound<iterator>(*this, __x);
842860 }
843861
844862 template <class _Kp>
845863 requires __is_compare_transparent
846 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
864 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
847865 return __upper_bound<const_iterator>(*this, __x);
848866 }
849867
850 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const key_type& __x) {
868 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
869 equal_range(const key_type& __x) {
851870 return __equal_range_impl(*this, __x);
852871 }
853872
854 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
873 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
855874 equal_range(const key_type& __x) const {
856875 return __equal_range_impl(*this, __x);
857876 }
858877
859878 template <class _Kp>
860879 requires __is_compare_transparent
861 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const _Kp& __x) {
880 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
881 equal_range(const _Kp& __x) {
862882 return __equal_range_impl(*this, __x);
863883 }
864884 template <class _Kp>
865885 requires __is_compare_transparent
866 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
886 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
867887 equal_range(const _Kp& __x) const {
868888 return __equal_range_impl(*this, __x);
869889 }
......@@ -878,7 +898,8 @@ public:
878898 __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
879899 }
880900
881 friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_map& __x, flat_map& __y) noexcept {
901 friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
902 swap(flat_map& __x, flat_map& __y) noexcept(noexcept(__x.swap(__y))) {
882903 __x.swap(__y);
883904 }
884905
......@@ -913,7 +934,7 @@ private:
913934 __compare_(std::forward<_CompArg>(__comp)...) {}
914935
915936 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_sorted_and_unique(auto&& __key_container) const {
916 auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) { return !__compare_(__x, __y); };
937 auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) -> bool { return !__compare_(__x, __y); };
917938 return ranges::adjacent_find(__key_container, __greater_or_equal_to) == ranges::end(__key_container);
918939 }
919940
......@@ -946,7 +967,7 @@ private:
946967 auto __zv = ranges::views::zip(__containers_.keys, __containers_.values);
947968 auto __append_start_offset = __containers_.keys.size() - __num_of_appended;
948969 auto __end = __zv.end();
949 auto __compare_key = [this](const auto& __p1, const auto& __p2) {
970 auto __compare_key = [this](const auto& __p1, const auto& __p2) -> bool {
950971 return __compare_(std::get<0>(__p1), std::get<0>(__p2));
951972 };
952973 if constexpr (!_WasSorted) {
......@@ -1125,8 +1146,7 @@ private:
11251146};
11261147
11271148template <class _KeyContainer, class _MappedContainer, class _Compare = less<typename _KeyContainer::value_type>>
1128 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
1129 !__is_allocator<_MappedContainer>::value &&
1149 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> && !__is_allocator_v<_MappedContainer> &&
11301150 is_invocable_v<const _Compare&,
11311151 const typename _KeyContainer::value_type&,
11321152 const typename _KeyContainer::value_type&>)
......@@ -1139,7 +1159,7 @@ flat_map(_KeyContainer, _MappedContainer, _Compare = _Compare())
11391159
11401160template <class _KeyContainer, class _MappedContainer, class _Allocator>
11411161 requires(uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> &&
1142 !__is_allocator<_KeyContainer>::value && !__is_allocator<_MappedContainer>::value)
1162 !__is_allocator_v<_KeyContainer> && !__is_allocator_v<_MappedContainer>)
11431163flat_map(_KeyContainer, _MappedContainer, _Allocator)
11441164 -> flat_map<typename _KeyContainer::value_type,
11451165 typename _MappedContainer::value_type,
......@@ -1148,9 +1168,8 @@ flat_map(_KeyContainer, _MappedContainer, _Allocator)
11481168 _MappedContainer>;
11491169
11501170template <class _KeyContainer, class _MappedContainer, class _Compare, class _Allocator>
1151 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
1152 !__is_allocator<_MappedContainer>::value && uses_allocator_v<_KeyContainer, _Allocator> &&
1153 uses_allocator_v<_MappedContainer, _Allocator> &&
1171 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> && !__is_allocator_v<_MappedContainer> &&
1172 uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> &&
11541173 is_invocable_v<const _Compare&,
11551174 const typename _KeyContainer::value_type&,
11561175 const typename _KeyContainer::value_type&>)
......@@ -1162,8 +1181,7 @@ flat_map(_KeyContainer, _MappedContainer, _Compare, _Allocator)
11621181 _MappedContainer>;
11631182
11641183template <class _KeyContainer, class _MappedContainer, class _Compare = less<typename _KeyContainer::value_type>>
1165 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
1166 !__is_allocator<_MappedContainer>::value &&
1184 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> && !__is_allocator_v<_MappedContainer> &&
11671185 is_invocable_v<const _Compare&,
11681186 const typename _KeyContainer::value_type&,
11691187 const typename _KeyContainer::value_type&>)
......@@ -1176,7 +1194,7 @@ flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Compare = _Compare()
11761194
11771195template <class _KeyContainer, class _MappedContainer, class _Allocator>
11781196 requires(uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> &&
1179 !__is_allocator<_KeyContainer>::value && !__is_allocator<_MappedContainer>::value)
1197 !__is_allocator_v<_KeyContainer> && !__is_allocator_v<_MappedContainer>)
11801198flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Allocator)
11811199 -> flat_map<typename _KeyContainer::value_type,
11821200 typename _MappedContainer::value_type,
......@@ -1185,9 +1203,8 @@ flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Allocator)
11851203 _MappedContainer>;
11861204
11871205template <class _KeyContainer, class _MappedContainer, class _Compare, class _Allocator>
1188 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
1189 !__is_allocator<_MappedContainer>::value && uses_allocator_v<_KeyContainer, _Allocator> &&
1190 uses_allocator_v<_MappedContainer, _Allocator> &&
1206 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> && !__is_allocator_v<_MappedContainer> &&
1207 uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> &&
11911208 is_invocable_v<const _Compare&,
11921209 const typename _KeyContainer::value_type&,
11931210 const typename _KeyContainer::value_type&>)
......@@ -1199,19 +1216,19 @@ flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Compare, _Allocator)
11991216 _MappedContainer>;
12001217
12011218template <class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>>
1202 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value)
1219 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator_v<_Compare>)
12031220flat_map(_InputIterator, _InputIterator, _Compare = _Compare())
12041221 -> flat_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare>;
12051222
12061223template <class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>>
1207 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value)
1224 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator_v<_Compare>)
12081225flat_map(sorted_unique_t, _InputIterator, _InputIterator, _Compare = _Compare())
12091226 -> flat_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare>;
12101227
12111228template <ranges::input_range _Range,
12121229 class _Compare = less<__range_key_type<_Range>>,
12131230 class _Allocator = allocator<byte>,
1214 class = __enable_if_t<!__is_allocator<_Compare>::value && __is_allocator<_Allocator>::value>>
1231 class = __enable_if_t<!__is_allocator_v<_Compare> && __is_allocator_v<_Allocator>>>
12151232flat_map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) -> flat_map<
12161233 __range_key_type<_Range>,
12171234 __range_mapped_type<_Range>,
......@@ -1219,7 +1236,7 @@ flat_map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator(
12191236 vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>,
12201237 vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
12211238
1222template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator<_Allocator>::value>>
1239template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator_v<_Allocator>>>
12231240flat_map(from_range_t, _Range&&, _Allocator) -> flat_map<
12241241 __range_key_type<_Range>,
12251242 __range_mapped_type<_Range>,
......@@ -1228,11 +1245,11 @@ flat_map(from_range_t, _Range&&, _Allocator) -> flat_map<
12281245 vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
12291246
12301247template <class _Key, class _Tp, class _Compare = less<_Key>>
1231 requires(!__is_allocator<_Compare>::value)
1248 requires(!__is_allocator_v<_Compare>)
12321249flat_map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare()) -> flat_map<_Key, _Tp, _Compare>;
12331250
12341251template <class _Key, class _Tp, class _Compare = less<_Key>>
1235 requires(!__is_allocator<_Compare>::value)
1252 requires(!__is_allocator_v<_Compare>)
12361253flat_map(sorted_unique_t, initializer_list<pair<_Key, _Tp>>, _Compare = _Compare()) -> flat_map<_Key, _Tp, _Compare>;
12371254
12381255template <class _Key, class _Tp, class _Compare, class _KeyContainer, class _MappedContainer, class _Allocator>
lib/libcxx/include/__flat_map/flat_multimap.h+251-172
......@@ -22,7 +22,6 @@
2222#include <__algorithm/upper_bound.h>
2323#include <__assert>
2424#include <__compare/synth_three_way.h>
25#include <__concepts/convertible_to.h>
2625#include <__concepts/swappable.h>
2726#include <__config>
2827#include <__cstddef/byte.h>
......@@ -30,7 +29,6 @@
3029#include <__flat_map/key_value_iterator.h>
3130#include <__flat_map/sorted_equivalent.h>
3231#include <__flat_map/utils.h>
33#include <__functional/invoke.h>
3432#include <__functional/is_transparent.h>
3533#include <__functional/operations.h>
3634#include <__fwd/vector.h>
......@@ -47,7 +45,7 @@
4745#include <__ranges/container_compatible_range.h>
4846#include <__ranges/drop_view.h>
4947#include <__ranges/from_range.h>
50#include <__ranges/ref_view.h>
48#include <__ranges/range_adaptor.h>
5149#include <__ranges/size.h>
5250#include <__ranges/subrange.h>
5351#include <__ranges/zip_view.h>
......@@ -57,14 +55,12 @@
5755#include <__type_traits/is_allocator.h>
5856#include <__type_traits/is_nothrow_constructible.h>
5957#include <__type_traits/is_same.h>
60#include <__type_traits/maybe_const.h>
6158#include <__utility/exception_guard.h>
6259#include <__utility/move.h>
6360#include <__utility/pair.h>
6461#include <__utility/scope_guard.h>
6562#include <__vector/vector.h>
6663#include <initializer_list>
67#include <stdexcept>
6864
6965#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
7066# pragma GCC system_header
......@@ -114,11 +110,12 @@ public:
114110 class value_compare {
115111 private:
116112 _LIBCPP_NO_UNIQUE_ADDRESS key_compare __comp_;
117 _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : __comp_(__c) {}
113 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare(key_compare __c) : __comp_(__c) {}
118114 friend flat_multimap;
119115
120116 public:
121 _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const {
117 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
118 operator()(const_reference __x, const_reference __y) const {
122119 return __comp_(__x.first, __y.first);
123120 }
124121 };
......@@ -137,17 +134,17 @@ private:
137134
138135public:
139136 // [flat.map.cons], construct/copy/destroy
140 _LIBCPP_HIDE_FROM_ABI flat_multimap() noexcept(
137 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap() noexcept(
141138 is_nothrow_default_constructible_v<_KeyContainer> && is_nothrow_default_constructible_v<_MappedContainer> &&
142139 is_nothrow_default_constructible_v<_Compare>)
143140 : __containers_(), __compare_() {}
144141
145 _LIBCPP_HIDE_FROM_ABI flat_multimap(const flat_multimap&) = default;
142 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(const flat_multimap&) = default;
146143
147144 // The copy/move constructors are not specified in the spec, which means they should be defaulted.
148145 // However, the move constructor can potentially leave a moved-from object in an inconsistent
149146 // state if an exception is thrown.
150 _LIBCPP_HIDE_FROM_ABI flat_multimap(flat_multimap&& __other) noexcept(
147 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(flat_multimap&& __other) noexcept(
151148 is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_MappedContainer> &&
152149 is_nothrow_move_constructible_v<_Compare>)
153150# if _LIBCPP_HAS_EXCEPTIONS
......@@ -168,7 +165,8 @@ public:
168165
169166 template <class _Allocator>
170167 requires __allocator_ctor_constraint<_Allocator>
171 _LIBCPP_HIDE_FROM_ABI flat_multimap(const flat_multimap& __other, const _Allocator& __alloc)
168 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
169 flat_multimap(const flat_multimap& __other, const _Allocator& __alloc)
172170 : flat_multimap(__ctor_uses_allocator_tag{},
173171 __alloc,
174172 __other.__containers_.keys,
......@@ -177,7 +175,7 @@ public:
177175
178176 template <class _Allocator>
179177 requires __allocator_ctor_constraint<_Allocator>
180 _LIBCPP_HIDE_FROM_ABI flat_multimap(flat_multimap&& __other, const _Allocator& __alloc)
178 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(flat_multimap&& __other, const _Allocator& __alloc)
181179# if _LIBCPP_HAS_EXCEPTIONS
182180 try
183181# endif // _LIBCPP_HAS_EXCEPTIONS
......@@ -194,7 +192,7 @@ public:
194192# endif // _LIBCPP_HAS_EXCEPTIONS
195193 }
196194
197 _LIBCPP_HIDE_FROM_ABI flat_multimap(
195 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(
198196 key_container_type __key_cont, mapped_container_type __mapped_cont, const key_compare& __comp = key_compare())
199197 : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) {
200198 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
......@@ -204,7 +202,7 @@ public:
204202
205203 template <class _Allocator>
206204 requires __allocator_ctor_constraint<_Allocator>
207 _LIBCPP_HIDE_FROM_ABI flat_multimap(
205 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(
208206 const key_container_type& __key_cont, const mapped_container_type& __mapped_cont, const _Allocator& __alloc)
209207 : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) {
210208 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
......@@ -214,22 +212,22 @@ public:
214212
215213 template <class _Allocator>
216214 requires __allocator_ctor_constraint<_Allocator>
217 _LIBCPP_HIDE_FROM_ABI
218 flat_multimap(const key_container_type& __key_cont,
219 const mapped_container_type& __mapped_cont,
220 const key_compare& __comp,
221 const _Allocator& __alloc)
215 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(
216 const key_container_type& __key_cont,
217 const mapped_container_type& __mapped_cont,
218 const key_compare& __comp,
219 const _Allocator& __alloc)
222220 : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) {
223221 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
224222 "flat_multimap keys and mapped containers have different size");
225223 __sort();
226224 }
227225
228 _LIBCPP_HIDE_FROM_ABI
229 flat_multimap(sorted_equivalent_t,
230 key_container_type __key_cont,
231 mapped_container_type __mapped_cont,
232 const key_compare& __comp = key_compare())
226 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(
227 sorted_equivalent_t,
228 key_container_type __key_cont,
229 mapped_container_type __mapped_cont,
230 const key_compare& __comp = key_compare())
233231 : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) {
234232 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
235233 "flat_multimap keys and mapped containers have different size");
......@@ -238,11 +236,11 @@ public:
238236
239237 template <class _Allocator>
240238 requires __allocator_ctor_constraint<_Allocator>
241 _LIBCPP_HIDE_FROM_ABI
242 flat_multimap(sorted_equivalent_t,
243 const key_container_type& __key_cont,
244 const mapped_container_type& __mapped_cont,
245 const _Allocator& __alloc)
239 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(
240 sorted_equivalent_t,
241 const key_container_type& __key_cont,
242 const mapped_container_type& __mapped_cont,
243 const _Allocator& __alloc)
246244 : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) {
247245 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
248246 "flat_multimap keys and mapped containers have different size");
......@@ -251,33 +249,35 @@ public:
251249
252250 template <class _Allocator>
253251 requires __allocator_ctor_constraint<_Allocator>
254 _LIBCPP_HIDE_FROM_ABI
255 flat_multimap(sorted_equivalent_t,
256 const key_container_type& __key_cont,
257 const mapped_container_type& __mapped_cont,
258 const key_compare& __comp,
259 const _Allocator& __alloc)
252 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(
253 sorted_equivalent_t,
254 const key_container_type& __key_cont,
255 const mapped_container_type& __mapped_cont,
256 const key_compare& __comp,
257 const _Allocator& __alloc)
260258 : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) {
261259 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
262260 "flat_multimap keys and mapped containers have different size");
263261 _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted(__containers_.keys), "Key container is not sorted");
264262 }
265263
266 _LIBCPP_HIDE_FROM_ABI explicit flat_multimap(const key_compare& __comp) : __containers_(), __compare_(__comp) {}
264 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_multimap(const key_compare& __comp)
265 : __containers_(), __compare_(__comp) {}
267266
268267 template <class _Allocator>
269268 requires __allocator_ctor_constraint<_Allocator>
270 _LIBCPP_HIDE_FROM_ABI flat_multimap(const key_compare& __comp, const _Allocator& __alloc)
269 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
270 flat_multimap(const key_compare& __comp, const _Allocator& __alloc)
271271 : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {}
272272
273273 template <class _Allocator>
274274 requires __allocator_ctor_constraint<_Allocator>
275 _LIBCPP_HIDE_FROM_ABI explicit flat_multimap(const _Allocator& __alloc)
275 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_multimap(const _Allocator& __alloc)
276276 : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) {}
277277
278278 template <class _InputIterator>
279279 requires __has_input_iterator_category<_InputIterator>::value
280 _LIBCPP_HIDE_FROM_ABI
280 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
281281 flat_multimap(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare())
282282 : __containers_(), __compare_(__comp) {
283283 insert(__first, __last);
......@@ -285,7 +285,7 @@ public:
285285
286286 template <class _InputIterator, class _Allocator>
287287 requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)
288 _LIBCPP_HIDE_FROM_ABI
288 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
289289 flat_multimap(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc)
290290 : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {
291291 insert(__first, __last);
......@@ -293,91 +293,99 @@ public:
293293
294294 template <class _InputIterator, class _Allocator>
295295 requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)
296 _LIBCPP_HIDE_FROM_ABI flat_multimap(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc)
296 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
297 flat_multimap(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc)
297298 : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) {
298299 insert(__first, __last);
299300 }
300301
301302 template <_ContainerCompatibleRange<value_type> _Range>
302 _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t __fr, _Range&& __rg)
303 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(from_range_t __fr, _Range&& __rg)
303304 : flat_multimap(__fr, std::forward<_Range>(__rg), key_compare()) {}
304305
305306 template <_ContainerCompatibleRange<value_type> _Range, class _Allocator>
306307 requires __allocator_ctor_constraint<_Allocator>
307 _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const _Allocator& __alloc)
308 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
309 flat_multimap(from_range_t, _Range&& __rg, const _Allocator& __alloc)
308310 : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) {
309311 insert_range(std::forward<_Range>(__rg));
310312 }
311313
312314 template <_ContainerCompatibleRange<value_type> _Range>
313 _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp) : flat_multimap(__comp) {
315 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
316 flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp)
317 : flat_multimap(__comp) {
314318 insert_range(std::forward<_Range>(__rg));
315319 }
316320
317321 template <_ContainerCompatibleRange<value_type> _Range, class _Allocator>
318322 requires __allocator_ctor_constraint<_Allocator>
319 _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc)
323 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
324 flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc)
320325 : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {
321326 insert_range(std::forward<_Range>(__rg));
322327 }
323328
324329 template <class _InputIterator>
325330 requires __has_input_iterator_category<_InputIterator>::value
326 _LIBCPP_HIDE_FROM_ABI flat_multimap(
331 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(
327332 sorted_equivalent_t, _InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare())
328333 : __containers_(), __compare_(__comp) {
329334 insert(sorted_equivalent, __first, __last);
330335 }
331336 template <class _InputIterator, class _Allocator>
332337 requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)
333 _LIBCPP_HIDE_FROM_ABI
334 flat_multimap(sorted_equivalent_t,
335 _InputIterator __first,
336 _InputIterator __last,
337 const key_compare& __comp,
338 const _Allocator& __alloc)
338 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(
339 sorted_equivalent_t,
340 _InputIterator __first,
341 _InputIterator __last,
342 const key_compare& __comp,
343 const _Allocator& __alloc)
339344 : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {
340345 insert(sorted_equivalent, __first, __last);
341346 }
342347
343348 template <class _InputIterator, class _Allocator>
344349 requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)
345 _LIBCPP_HIDE_FROM_ABI
350 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
346351 flat_multimap(sorted_equivalent_t, _InputIterator __first, _InputIterator __last, const _Allocator& __alloc)
347352 : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) {
348353 insert(sorted_equivalent, __first, __last);
349354 }
350355
351 _LIBCPP_HIDE_FROM_ABI flat_multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
356 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
357 flat_multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
352358 : flat_multimap(__il.begin(), __il.end(), __comp) {}
353359
354360 template <class _Allocator>
355361 requires __allocator_ctor_constraint<_Allocator>
356 _LIBCPP_HIDE_FROM_ABI
362 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
357363 flat_multimap(initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc)
358364 : flat_multimap(__il.begin(), __il.end(), __comp, __alloc) {}
359365
360366 template <class _Allocator>
361367 requires __allocator_ctor_constraint<_Allocator>
362 _LIBCPP_HIDE_FROM_ABI flat_multimap(initializer_list<value_type> __il, const _Allocator& __alloc)
368 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
369 flat_multimap(initializer_list<value_type> __il, const _Allocator& __alloc)
363370 : flat_multimap(__il.begin(), __il.end(), __alloc) {}
364371
365 _LIBCPP_HIDE_FROM_ABI
372 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
366373 flat_multimap(sorted_equivalent_t, initializer_list<value_type> __il, const key_compare& __comp = key_compare())
367374 : flat_multimap(sorted_equivalent, __il.begin(), __il.end(), __comp) {}
368375
369376 template <class _Allocator>
370377 requires __allocator_ctor_constraint<_Allocator>
371 _LIBCPP_HIDE_FROM_ABI flat_multimap(
378 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(
372379 sorted_equivalent_t, initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc)
373380 : flat_multimap(sorted_equivalent, __il.begin(), __il.end(), __comp, __alloc) {}
374381
375382 template <class _Allocator>
376383 requires __allocator_ctor_constraint<_Allocator>
377 _LIBCPP_HIDE_FROM_ABI flat_multimap(sorted_equivalent_t, initializer_list<value_type> __il, const _Allocator& __alloc)
384 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
385 flat_multimap(sorted_equivalent_t, initializer_list<value_type> __il, const _Allocator& __alloc)
378386 : flat_multimap(sorted_equivalent, __il.begin(), __il.end(), __alloc) {}
379387
380 _LIBCPP_HIDE_FROM_ABI flat_multimap& operator=(initializer_list<value_type> __il) {
388 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap& operator=(initializer_list<value_type> __il) {
381389 clear();
382390 insert(__il);
383391 return *this;
......@@ -386,9 +394,9 @@ public:
386394 // copy/move assignment are not specified in the spec (defaulted)
387395 // but move assignment can potentially leave moved from object in an inconsistent
388396 // state if an exception is thrown
389 _LIBCPP_HIDE_FROM_ABI flat_multimap& operator=(const flat_multimap&) = default;
397 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap& operator=(const flat_multimap&) = default;
390398
391 _LIBCPP_HIDE_FROM_ABI flat_multimap& operator=(flat_multimap&& __other) noexcept(
399 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap& operator=(flat_multimap&& __other) noexcept(
392400 is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_MappedContainer> &&
393401 is_nothrow_move_assignable_v<_Compare>) {
394402 auto __clear_other_guard = std::__make_scope_guard([&]() noexcept { __other.clear() /* noexcept */; });
......@@ -400,38 +408,58 @@ public:
400408 }
401409
402410 // iterators
403 _LIBCPP_HIDE_FROM_ABI iterator begin() noexcept {
411 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
404412 return iterator(__containers_.keys.begin(), __containers_.values.begin());
405413 }
406414
407 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept {
415 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
408416 return const_iterator(__containers_.keys.begin(), __containers_.values.begin());
409417 }
410418
411 _LIBCPP_HIDE_FROM_ABI iterator end() noexcept {
419 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
412420 return iterator(__containers_.keys.end(), __containers_.values.end());
413421 }
414422
415 _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept {
423 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
416424 return const_iterator(__containers_.keys.end(), __containers_.values.end());
417425 }
418426
419 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
420 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
421 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
422 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
427 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
428 return reverse_iterator(end());
429 }
430 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
431 return const_reverse_iterator(end());
432 }
433 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
434 return reverse_iterator(begin());
435 }
436 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
437 return const_reverse_iterator(begin());
438 }
423439
424 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return begin(); }
425 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return end(); }
426 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
427 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
440 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept {
441 return begin();
442 }
443 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept {
444 return end();
445 }
446 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
447 return const_reverse_iterator(end());
448 }
449 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
450 return const_reverse_iterator(begin());
451 }
428452
429453 // [flat.map.capacity], capacity
430 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __containers_.keys.empty(); }
454 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool empty() const noexcept {
455 return __containers_.keys.empty();
456 }
431457
432 _LIBCPP_HIDE_FROM_ABI size_type size() const noexcept { return __containers_.keys.size(); }
458 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
459 return __containers_.keys.size();
460 }
433461
434 _LIBCPP_HIDE_FROM_ABI size_type max_size() const noexcept {
462 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
435463 return std::min<size_type>(__containers_.keys.max_size(), __containers_.values.max_size());
436464 }
437465
......@@ -439,7 +467,7 @@ public:
439467 template <class... _Args>
440468 requires is_constructible_v<pair<key_type, mapped_type>, _Args...> && is_move_constructible_v<key_type> &&
441469 is_move_constructible_v<mapped_type>
442 _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) {
470 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator emplace(_Args&&... __args) {
443471 std::pair<key_type, mapped_type> __pair(std::forward<_Args>(__args)...);
444472 auto __key_it = std::upper_bound(__containers_.keys.begin(), __containers_.keys.end(), __pair.first, __compare_);
445473 auto __mapped_it = __corresponding_mapped_it(*this, __key_it);
......@@ -450,7 +478,7 @@ public:
450478
451479 template <class... _Args>
452480 requires is_constructible_v<pair<key_type, mapped_type>, _Args...>
453 _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __hint, _Args&&... __args) {
481 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator emplace_hint(const_iterator __hint, _Args&&... __args) {
454482 std::pair<key_type, mapped_type> __pair(std::forward<_Args>(__args)...);
455483
456484 auto __prev_larger = __hint != cbegin() && __compare_(__pair.first, (__hint - 1)->first);
......@@ -490,33 +518,35 @@ public:
490518 *this, __key_iter, __mapped_iter, std::move(__pair.first), std::move(__pair.second));
491519 }
492520
493 _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __x) { return emplace(__x); }
521 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const value_type& __x) { return emplace(__x); }
494522
495 _LIBCPP_HIDE_FROM_ABI iterator insert(value_type&& __x) { return emplace(std::move(__x)); }
523 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(value_type&& __x) {
524 return emplace(std::move(__x));
525 }
496526
497 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, const value_type& __x) {
527 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, const value_type& __x) {
498528 return emplace_hint(__hint, __x);
499529 }
500530
501 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, value_type&& __x) {
531 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, value_type&& __x) {
502532 return emplace_hint(__hint, std::move(__x));
503533 }
504534
505535 template <class _PairLike>
506536 requires is_constructible_v<pair<key_type, mapped_type>, _PairLike>
507 _LIBCPP_HIDE_FROM_ABI iterator insert(_PairLike&& __x) {
537 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(_PairLike&& __x) {
508538 return emplace(std::forward<_PairLike>(__x));
509539 }
510540
511541 template <class _PairLike>
512542 requires is_constructible_v<pair<key_type, mapped_type>, _PairLike>
513 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, _PairLike&& __x) {
543 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, _PairLike&& __x) {
514544 return emplace_hint(__hint, std::forward<_PairLike>(__x));
515545 }
516546
517547 template <class _InputIterator>
518548 requires __has_input_iterator_category<_InputIterator>::value
519 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last) {
549 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(_InputIterator __first, _InputIterator __last) {
520550 if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) {
521551 __reserve(__last - __first);
522552 }
......@@ -525,7 +555,8 @@ public:
525555
526556 template <class _InputIterator>
527557 requires __has_input_iterator_category<_InputIterator>::value
528 _LIBCPP_HIDE_FROM_ABI void insert(sorted_equivalent_t, _InputIterator __first, _InputIterator __last) {
558 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
559 insert(sorted_equivalent_t, _InputIterator __first, _InputIterator __last) {
529560 if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) {
530561 __reserve(__last - __first);
531562 }
......@@ -534,7 +565,7 @@ public:
534565 }
535566
536567 template <_ContainerCompatibleRange<value_type> _Range>
537 _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
568 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(_Range&& __range) {
538569 if constexpr (ranges::sized_range<_Range>) {
539570 __reserve(ranges::size(__range));
540571 }
......@@ -542,19 +573,32 @@ public:
542573 __append_sort_merge</*WasSorted = */ false>(ranges::begin(__range), ranges::end(__range));
543574 }
544575
545 _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
576 template <_ContainerCompatibleRange<value_type> _Range>
577 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(sorted_equivalent_t, _Range&& __range) {
578 if constexpr (ranges::sized_range<_Range>) {
579 __reserve(ranges::size(__range));
580 }
581
582 __append_sort_merge</*WasSorted = */ true>(ranges::begin(__range), ranges::end(__range));
583 }
584
585 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(initializer_list<value_type> __il) {
586 insert(__il.begin(), __il.end());
587 }
546588
547 _LIBCPP_HIDE_FROM_ABI void insert(sorted_equivalent_t, initializer_list<value_type> __il) {
589 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
590 insert(sorted_equivalent_t, initializer_list<value_type> __il) {
548591 insert(sorted_equivalent, __il.begin(), __il.end());
549592 }
550593
551 _LIBCPP_HIDE_FROM_ABI containers extract() && {
594 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && {
552595 auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; });
553596 auto __ret = std::move(__containers_);
554597 return __ret;
555598 }
556599
557 _LIBCPP_HIDE_FROM_ABI void replace(key_container_type&& __key_cont, mapped_container_type&& __mapped_cont) {
600 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
601 replace(key_container_type&& __key_cont, mapped_container_type&& __mapped_cont) {
558602 _LIBCPP_ASSERT_VALID_INPUT_RANGE(
559603 __key_cont.size() == __mapped_cont.size(), "flat_multimap keys and mapped containers have different size");
560604
......@@ -565,15 +609,15 @@ public:
565609 __guard.__complete();
566610 }
567611
568 _LIBCPP_HIDE_FROM_ABI iterator erase(iterator __position) {
612 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(iterator __position) {
569613 return __erase(__position.__key_iter_, __position.__mapped_iter_);
570614 }
571615
572 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __position) {
616 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __position) {
573617 return __erase(__position.__key_iter_, __position.__mapped_iter_);
574618 }
575619
576 _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __x) {
620 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type erase(const key_type& __x) {
577621 auto [__first, __last] = equal_range(__x);
578622 auto __res = __last - __first;
579623 erase(__first, __last);
......@@ -583,14 +627,14 @@ public:
583627 template <class _Kp>
584628 requires(__is_compare_transparent && !is_convertible_v<_Kp &&, iterator> &&
585629 !is_convertible_v<_Kp &&, const_iterator>)
586 _LIBCPP_HIDE_FROM_ABI size_type erase(_Kp&& __x) {
630 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type erase(_Kp&& __x) {
587631 auto [__first, __last] = equal_range(__x);
588632 auto __res = __last - __first;
589633 erase(__first, __last);
590634 return __res;
591635 }
592636
593 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last) {
637 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __first, const_iterator __last) {
594638 auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
595639 auto __key_it = __containers_.keys.erase(__first.__key_iter_, __last.__key_iter_);
596640 auto __mapped_it = __containers_.values.erase(__first.__mapped_iter_, __last.__mapped_iter_);
......@@ -598,146 +642,178 @@ public:
598642 return iterator(std::move(__key_it), std::move(__mapped_it));
599643 }
600644
601 _LIBCPP_HIDE_FROM_ABI void swap(flat_multimap& __y) noexcept {
602 // warning: The spec has unconditional noexcept, which means that
603 // if any of the following functions throw an exception,
604 // std::terminate will be called
645 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_multimap& __y) noexcept(
646 is_nothrow_swappable_v<key_container_type> && is_nothrow_swappable_v<mapped_container_type> &&
647 is_nothrow_swappable_v<key_compare>) {
648 auto __on_failure = std::__make_exception_guard([&]() noexcept {
649 clear() /* noexcept */;
650 __y.clear() /* noexcept */;
651 });
605652 ranges::swap(__compare_, __y.__compare_);
606653 ranges::swap(__containers_.keys, __y.__containers_.keys);
607654 ranges::swap(__containers_.values, __y.__containers_.values);
655 __on_failure.__complete();
608656 }
609657
610 _LIBCPP_HIDE_FROM_ABI void clear() noexcept {
658 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept {
611659 __containers_.keys.clear();
612660 __containers_.values.clear();
613661 }
614662
615663 // observers
616 _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __compare_; }
617 _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return value_compare(__compare_); }
664 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
665 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
666 return value_compare(__compare_);
667 }
618668
619 _LIBCPP_HIDE_FROM_ABI const key_container_type& keys() const noexcept { return __containers_.keys; }
620 _LIBCPP_HIDE_FROM_ABI const mapped_container_type& values() const noexcept { return __containers_.values; }
669 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept {
670 return __containers_.keys;
671 }
672 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type&
673 values() const noexcept {
674 return __containers_.values;
675 }
621676
622677 // map operations
623 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __x) { return __find_impl(*this, __x); }
678 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
679 return __find_impl(*this, __x);
680 }
624681
625 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __x) const { return __find_impl(*this, __x); }
682 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
683 return __find_impl(*this, __x);
684 }
626685
627686 template <class _Kp>
628687 requires __is_compare_transparent
629 _LIBCPP_HIDE_FROM_ABI iterator find(const _Kp& __x) {
688 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
630689 return __find_impl(*this, __x);
631690 }
632691
633692 template <class _Kp>
634693 requires __is_compare_transparent
635 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Kp& __x) const {
694 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
636695 return __find_impl(*this, __x);
637696 }
638697
639 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __x) const {
698 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
640699 auto [__first, __last] = equal_range(__x);
641700 return __last - __first;
642701 }
643702
644703 template <class _Kp>
645704 requires __is_compare_transparent
646 _LIBCPP_HIDE_FROM_ABI size_type count(const _Kp& __x) const {
705 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
647706 auto [__first, __last] = equal_range(__x);
648707 return __last - __first;
649708 }
650709
651 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __x) const { return find(__x) != end(); }
710 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
711 return find(__x) != end();
712 }
652713
653714 template <class _Kp>
654715 requires __is_compare_transparent
655 _LIBCPP_HIDE_FROM_ABI bool contains(const _Kp& __x) const {
716 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
656717 return find(__x) != end();
657718 }
658719
659 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __x) { return __lower_bound<iterator>(*this, __x); }
720 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
721 return __lower_bound<iterator>(*this, __x);
722 }
660723
661 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __x) const {
724 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
725 lower_bound(const key_type& __x) const {
662726 return __lower_bound<const_iterator>(*this, __x);
663727 }
664728
665729 template <class _Kp>
666730 requires __is_compare_transparent
667 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _Kp& __x) {
731 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
668732 return __lower_bound<iterator>(*this, __x);
669733 }
670734
671735 template <class _Kp>
672736 requires __is_compare_transparent
673 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _Kp& __x) const {
737 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
674738 return __lower_bound<const_iterator>(*this, __x);
675739 }
676740
677 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __x) { return __upper_bound<iterator>(*this, __x); }
741 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
742 return __upper_bound<iterator>(*this, __x);
743 }
678744
679 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __x) const {
745 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
746 upper_bound(const key_type& __x) const {
680747 return __upper_bound<const_iterator>(*this, __x);
681748 }
682749
683750 template <class _Kp>
684751 requires __is_compare_transparent
685 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _Kp& __x) {
752 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
686753 return __upper_bound<iterator>(*this, __x);
687754 }
688755
689756 template <class _Kp>
690757 requires __is_compare_transparent
691 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _Kp& __x) const {
758 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
692759 return __upper_bound<const_iterator>(*this, __x);
693760 }
694761
695 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __x) {
762 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
763 equal_range(const key_type& __x) {
696764 return __equal_range_impl(*this, __x);
697765 }
698766
699 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __x) const {
767 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
768 equal_range(const key_type& __x) const {
700769 return __equal_range_impl(*this, __x);
701770 }
702771
703772 template <class _Kp>
704773 requires __is_compare_transparent
705 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _Kp& __x) {
774 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
775 equal_range(const _Kp& __x) {
706776 return __equal_range_impl(*this, __x);
707777 }
708778 template <class _Kp>
709779 requires __is_compare_transparent
710 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _Kp& __x) const {
780 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
781 equal_range(const _Kp& __x) const {
711782 return __equal_range_impl(*this, __x);
712783 }
713784
714 friend _LIBCPP_HIDE_FROM_ABI bool operator==(const flat_multimap& __x, const flat_multimap& __y) {
785 friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
786 operator==(const flat_multimap& __x, const flat_multimap& __y) {
715787 return ranges::equal(__x, __y);
716788 }
717789
718 friend _LIBCPP_HIDE_FROM_ABI auto operator<=>(const flat_multimap& __x, const flat_multimap& __y) {
790 friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 auto
791 operator<=>(const flat_multimap& __x, const flat_multimap& __y) {
719792 return std::lexicographical_compare_three_way(
720793 __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
721794 }
722795
723 friend _LIBCPP_HIDE_FROM_ABI void swap(flat_multimap& __x, flat_multimap& __y) noexcept { __x.swap(__y); }
796 friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
797 swap(flat_multimap& __x, flat_multimap& __y) noexcept(noexcept(__x.swap(__y))) {
798 __x.swap(__y);
799 }
724800
725801private:
726802 struct __ctor_uses_allocator_tag {
727 explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_tag() = default;
803 explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __ctor_uses_allocator_tag() = default;
728804 };
729805 struct __ctor_uses_allocator_empty_tag {
730 explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_empty_tag() = default;
806 explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __ctor_uses_allocator_empty_tag() = default;
731807 };
732808
733809 template <class _Allocator, class _KeyCont, class _MappedCont, class... _CompArg>
734810 requires __allocator_ctor_constraint<_Allocator>
735 _LIBCPP_HIDE_FROM_ABI
736 flat_multimap(__ctor_uses_allocator_tag,
737 const _Allocator& __alloc,
738 _KeyCont&& __key_cont,
739 _MappedCont&& __mapped_cont,
740 _CompArg&&... __comp)
811 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(
812 __ctor_uses_allocator_tag,
813 const _Allocator& __alloc,
814 _KeyCont&& __key_cont,
815 _MappedCont&& __mapped_cont,
816 _CompArg&&... __comp)
741817 : __containers_{.keys = std::make_obj_using_allocator<key_container_type>(
742818 __alloc, std::forward<_KeyCont>(__key_cont)),
743819 .values = std::make_obj_using_allocator<mapped_container_type>(
......@@ -746,36 +822,39 @@ private:
746822
747823 template <class _Allocator, class... _CompArg>
748824 requires __allocator_ctor_constraint<_Allocator>
749 _LIBCPP_HIDE_FROM_ABI flat_multimap(__ctor_uses_allocator_empty_tag, const _Allocator& __alloc, _CompArg&&... __comp)
825 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
826 flat_multimap(__ctor_uses_allocator_empty_tag, const _Allocator& __alloc, _CompArg&&... __comp)
750827 : __containers_{.keys = std::make_obj_using_allocator<key_container_type>(__alloc),
751828 .values = std::make_obj_using_allocator<mapped_container_type>(__alloc)},
752829 __compare_(std::forward<_CompArg>(__comp)...) {}
753830
754 _LIBCPP_HIDE_FROM_ABI bool __is_sorted(auto&& __key_container) const {
831 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_sorted(auto&& __key_container) const {
755832 return ranges::is_sorted(__key_container, __compare_);
756833 }
757834
758 _LIBCPP_HIDE_FROM_ABI void __sort() {
835 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __sort() {
759836 auto __zv = ranges::views::zip(__containers_.keys, __containers_.values);
760837 ranges::sort(__zv, __compare_, [](const auto& __p) -> decltype(auto) { return std::get<0>(__p); });
761838 }
762839
763840 template <class _Self, class _KeyIter>
764 _LIBCPP_HIDE_FROM_ABI static auto __corresponding_mapped_it(_Self&& __self, _KeyIter&& __key_iter) {
841 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto
842 __corresponding_mapped_it(_Self&& __self, _KeyIter&& __key_iter) {
765843 return __self.__containers_.values.begin() +
766844 static_cast<ranges::range_difference_t<mapped_container_type>>(
767845 ranges::distance(__self.__containers_.keys.begin(), __key_iter));
768846 }
769847
770848 template <bool _WasSorted, class _InputIterator, class _Sentinel>
771 _LIBCPP_HIDE_FROM_ABI void __append_sort_merge(_InputIterator __first, _Sentinel __last) {
849 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
850 __append_sort_merge(_InputIterator __first, _Sentinel __last) {
772851 auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
773852 size_t __num_appended = __flat_map_utils::__append(*this, std::move(__first), std::move(__last));
774853 if (__num_appended != 0) {
775854 auto __zv = ranges::views::zip(__containers_.keys, __containers_.values);
776855 auto __append_start_offset = __containers_.keys.size() - __num_appended;
777856 auto __end = __zv.end();
778 auto __compare_key = [this](const auto& __p1, const auto& __p2) {
857 auto __compare_key = [this](const auto& __p1, const auto& __p2) -> bool {
779858 return __compare_(std::get<0>(__p1), std::get<0>(__p2));
780859 };
781860 if constexpr (!_WasSorted) {
......@@ -791,7 +870,7 @@ private:
791870 }
792871
793872 template <class _Self, class _Kp>
794 _LIBCPP_HIDE_FROM_ABI static auto __find_impl(_Self&& __self, const _Kp& __key) {
873 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __find_impl(_Self&& __self, const _Kp& __key) {
795874 auto __it = __self.lower_bound(__key);
796875 auto __last = __self.end();
797876 if (__it == __last || __self.__compare_(__key, __it->first)) {
......@@ -801,7 +880,7 @@ private:
801880 }
802881
803882 template <class _Self, class _Kp>
804 _LIBCPP_HIDE_FROM_ABI static auto __equal_range_impl(_Self&& __self, const _Kp& __key) {
883 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __equal_range_impl(_Self&& __self, const _Kp& __key) {
805884 auto [__key_first, __key_last] =
806885 std::equal_range(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __key, __self.__compare_);
807886
......@@ -811,7 +890,7 @@ private:
811890 }
812891
813892 template <class _Res, class _Self, class _Kp>
814 _LIBCPP_HIDE_FROM_ABI static _Res __lower_bound(_Self&& __self, _Kp& __x) {
893 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static _Res __lower_bound(_Self&& __self, _Kp& __x) {
815894 auto __key_iter =
816895 std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_);
817896 auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter);
......@@ -819,14 +898,14 @@ private:
819898 }
820899
821900 template <class _Res, class _Self, class _Kp>
822 _LIBCPP_HIDE_FROM_ABI static _Res __upper_bound(_Self&& __self, _Kp& __x) {
901 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static _Res __upper_bound(_Self&& __self, _Kp& __x) {
823902 auto __key_iter =
824903 std::upper_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_);
825904 auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter);
826905 return _Res(std::move(__key_iter), std::move(__mapped_iter));
827906 }
828907
829 _LIBCPP_HIDE_FROM_ABI void __reserve(size_t __size) {
908 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __reserve(size_t __size) {
830909 if constexpr (__container_traits<_KeyContainer>::__reservable) {
831910 __containers_.keys.reserve(__size);
832911 }
......@@ -837,7 +916,8 @@ private:
837916 }
838917
839918 template <class _KIter, class _MIter>
840 _LIBCPP_HIDE_FROM_ABI iterator __erase(_KIter __key_iter_to_remove, _MIter __mapped_iter_to_remove) {
919 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator
920 __erase(_KIter __key_iter_to_remove, _MIter __mapped_iter_to_remove) {
841921 auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
842922 auto __key_iter = __containers_.keys.erase(__key_iter_to_remove);
843923 auto __mapped_iter = __containers_.values.erase(__mapped_iter_to_remove);
......@@ -847,7 +927,8 @@ private:
847927
848928 template <class _Key2, class _Tp2, class _Compare2, class _KeyContainer2, class _MappedContainer2, class _Predicate>
849929 friend typename flat_multimap<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>::size_type
850 erase_if(flat_multimap<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate);
930 _LIBCPP_CONSTEXPR_SINCE_CXX26
931 erase_if(flat_multimap<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate);
851932
852933 friend __flat_map_utils;
853934
......@@ -855,8 +936,9 @@ private:
855936 _LIBCPP_NO_UNIQUE_ADDRESS key_compare __compare_;
856937
857938 struct __key_equiv {
858 _LIBCPP_HIDE_FROM_ABI __key_equiv(key_compare __c) : __comp_(__c) {}
859 _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const {
939 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_equiv(key_compare __c) : __comp_(__c) {}
940 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
941 operator()(const_reference __x, const_reference __y) const {
860942 return !__comp_(std::get<0>(__x), std::get<0>(__y)) && !__comp_(std::get<0>(__y), std::get<0>(__x));
861943 }
862944 key_compare __comp_;
......@@ -864,8 +946,7 @@ private:
864946};
865947
866948template <class _KeyContainer, class _MappedContainer, class _Compare = less<typename _KeyContainer::value_type>>
867 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
868 !__is_allocator<_MappedContainer>::value &&
949 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> && !__is_allocator_v<_MappedContainer> &&
869950 is_invocable_v<const _Compare&,
870951 const typename _KeyContainer::value_type&,
871952 const typename _KeyContainer::value_type&>)
......@@ -878,7 +959,7 @@ flat_multimap(_KeyContainer, _MappedContainer, _Compare = _Compare())
878959
879960template <class _KeyContainer, class _MappedContainer, class _Allocator>
880961 requires(uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> &&
881 !__is_allocator<_KeyContainer>::value && !__is_allocator<_MappedContainer>::value)
962 !__is_allocator_v<_KeyContainer> && !__is_allocator_v<_MappedContainer>)
882963flat_multimap(_KeyContainer, _MappedContainer, _Allocator)
883964 -> flat_multimap<typename _KeyContainer::value_type,
884965 typename _MappedContainer::value_type,
......@@ -887,9 +968,8 @@ flat_multimap(_KeyContainer, _MappedContainer, _Allocator)
887968 _MappedContainer>;
888969
889970template <class _KeyContainer, class _MappedContainer, class _Compare, class _Allocator>
890 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
891 !__is_allocator<_MappedContainer>::value && uses_allocator_v<_KeyContainer, _Allocator> &&
892 uses_allocator_v<_MappedContainer, _Allocator> &&
971 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> && !__is_allocator_v<_MappedContainer> &&
972 uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> &&
893973 is_invocable_v<const _Compare&,
894974 const typename _KeyContainer::value_type&,
895975 const typename _KeyContainer::value_type&>)
......@@ -901,8 +981,7 @@ flat_multimap(_KeyContainer, _MappedContainer, _Compare, _Allocator)
901981 _MappedContainer>;
902982
903983template <class _KeyContainer, class _MappedContainer, class _Compare = less<typename _KeyContainer::value_type>>
904 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
905 !__is_allocator<_MappedContainer>::value &&
984 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> && !__is_allocator_v<_MappedContainer> &&
906985 is_invocable_v<const _Compare&,
907986 const typename _KeyContainer::value_type&,
908987 const typename _KeyContainer::value_type&>)
......@@ -915,7 +994,7 @@ flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Compare = _
915994
916995template <class _KeyContainer, class _MappedContainer, class _Allocator>
917996 requires(uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> &&
918 !__is_allocator<_KeyContainer>::value && !__is_allocator<_MappedContainer>::value)
997 !__is_allocator_v<_KeyContainer> && !__is_allocator_v<_MappedContainer>)
919998flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Allocator)
920999 -> flat_multimap<typename _KeyContainer::value_type,
9211000 typename _MappedContainer::value_type,
......@@ -924,9 +1003,8 @@ flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Allocator)
9241003 _MappedContainer>;
9251004
9261005template <class _KeyContainer, class _MappedContainer, class _Compare, class _Allocator>
927 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
928 !__is_allocator<_MappedContainer>::value && uses_allocator_v<_KeyContainer, _Allocator> &&
929 uses_allocator_v<_MappedContainer, _Allocator> &&
1006 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> && !__is_allocator_v<_MappedContainer> &&
1007 uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> &&
9301008 is_invocable_v<const _Compare&,
9311009 const typename _KeyContainer::value_type&,
9321010 const typename _KeyContainer::value_type&>)
......@@ -938,19 +1016,19 @@ flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Compare, _A
9381016 _MappedContainer>;
9391017
9401018template <class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>>
941 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value)
1019 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator_v<_Compare>)
9421020flat_multimap(_InputIterator, _InputIterator, _Compare = _Compare())
9431021 -> flat_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare>;
9441022
9451023template <class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>>
946 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value)
1024 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator_v<_Compare>)
9471025flat_multimap(sorted_equivalent_t, _InputIterator, _InputIterator, _Compare = _Compare())
9481026 -> flat_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare>;
9491027
9501028template <ranges::input_range _Range,
9511029 class _Compare = less<__range_key_type<_Range>>,
9521030 class _Allocator = allocator<byte>,
953 class = __enable_if_t<!__is_allocator<_Compare>::value && __is_allocator<_Allocator>::value>>
1031 class = __enable_if_t<!__is_allocator_v<_Compare> && __is_allocator_v<_Allocator>>>
9541032flat_multimap(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) -> flat_multimap<
9551033 __range_key_type<_Range>,
9561034 __range_mapped_type<_Range>,
......@@ -958,7 +1036,7 @@ flat_multimap(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Alloc
9581036 vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>,
9591037 vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
9601038
961template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator<_Allocator>::value>>
1039template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator_v<_Allocator>>>
9621040flat_multimap(from_range_t, _Range&&, _Allocator) -> flat_multimap<
9631041 __range_key_type<_Range>,
9641042 __range_mapped_type<_Range>,
......@@ -967,11 +1045,11 @@ flat_multimap(from_range_t, _Range&&, _Allocator) -> flat_multimap<
9671045 vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
9681046
9691047template <class _Key, class _Tp, class _Compare = less<_Key>>
970 requires(!__is_allocator<_Compare>::value)
1048 requires(!__is_allocator_v<_Compare>)
9711049flat_multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare()) -> flat_multimap<_Key, _Tp, _Compare>;
9721050
9731051template <class _Key, class _Tp, class _Compare = less<_Key>>
974 requires(!__is_allocator<_Compare>::value)
1052 requires(!__is_allocator_v<_Compare>)
9751053flat_multimap(sorted_equivalent_t, initializer_list<pair<_Key, _Tp>>, _Compare = _Compare())
9761054 -> flat_multimap<_Key, _Tp, _Compare>;
9771055
......@@ -980,8 +1058,9 @@ struct uses_allocator<flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedC
9801058 : bool_constant<uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator>> {};
9811059
9821060template <class _Key, class _Tp, class _Compare, class _KeyContainer, class _MappedContainer, class _Predicate>
983_LIBCPP_HIDE_FROM_ABI typename flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type
984erase_if(flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __flat_multimap, _Predicate __pred) {
1061_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
1062 typename flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type
1063 erase_if(flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __flat_multimap, _Predicate __pred) {
9851064 auto __zv = ranges::views::zip(__flat_multimap.__containers_.keys, __flat_multimap.__containers_.values);
9861065 auto __first = __zv.begin();
9871066 auto __last = __zv.end();
lib/libcxx/include/__flat_map/key_value_iterator.h-1
......@@ -20,7 +20,6 @@
2020#include <__type_traits/conditional.h>
2121#include <__utility/forward.h>
2222#include <__utility/move.h>
23#include <__utility/pair.h>
2423
2524#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2625# pragma GCC system_header
lib/libcxx/include/__flat_map/utils.h+1
......@@ -16,6 +16,7 @@
1616#include <__utility/exception_guard.h>
1717#include <__utility/forward.h>
1818#include <__utility/move.h>
19#include <__vector/container_traits.h>
1920
2021#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2122# pragma GCC system_header
lib/libcxx/include/__flat_set/flat_multiset.h+211-143
......@@ -13,54 +13,41 @@
1313#include <__algorithm/equal_range.h>
1414#include <__algorithm/lexicographical_compare_three_way.h>
1515#include <__algorithm/lower_bound.h>
16#include <__algorithm/min.h>
1716#include <__algorithm/ranges_equal.h>
1817#include <__algorithm/ranges_inplace_merge.h>
1918#include <__algorithm/ranges_is_sorted.h>
2019#include <__algorithm/ranges_sort.h>
21#include <__algorithm/ranges_unique.h>
2220#include <__algorithm/remove_if.h>
2321#include <__algorithm/upper_bound.h>
2422#include <__assert>
2523#include <__compare/synth_three_way.h>
26#include <__concepts/convertible_to.h>
2724#include <__concepts/swappable.h>
2825#include <__config>
29#include <__cstddef/byte.h>
30#include <__cstddef/ptrdiff_t.h>
31#include <__flat_map/key_value_iterator.h>
3226#include <__flat_map/sorted_equivalent.h>
3327#include <__flat_set/ra_iterator.h>
3428#include <__flat_set/utils.h>
35#include <__functional/invoke.h>
3629#include <__functional/is_transparent.h>
3730#include <__functional/operations.h>
3831#include <__fwd/vector.h>
3932#include <__iterator/concepts.h>
40#include <__iterator/distance.h>
4133#include <__iterator/iterator_traits.h>
4234#include <__iterator/prev.h>
43#include <__iterator/ranges_iterator_traits.h>
4435#include <__iterator/reverse_iterator.h>
4536#include <__memory/allocator_traits.h>
4637#include <__memory/uses_allocator.h>
4738#include <__memory/uses_allocator_construction.h>
48#include <__ranges/access.h>
4939#include <__ranges/concepts.h>
5040#include <__ranges/container_compatible_range.h>
5141#include <__ranges/drop_view.h>
5242#include <__ranges/from_range.h>
53#include <__ranges/ref_view.h>
43#include <__ranges/range_adaptor.h>
5444#include <__ranges/size.h>
5545#include <__ranges/subrange.h>
56#include <__ranges/zip_view.h>
57#include <__type_traits/conjunction.h>
5846#include <__type_traits/container_traits.h>
5947#include <__type_traits/invoke.h>
6048#include <__type_traits/is_allocator.h>
6149#include <__type_traits/is_nothrow_constructible.h>
6250#include <__type_traits/is_same.h>
63#include <__type_traits/maybe_const.h>
6451#include <__utility/as_const.h>
6552#include <__utility/exception_guard.h>
6653#include <__utility/move.h>
......@@ -108,16 +95,16 @@ public:
10895
10996public:
11097 // [flat.multiset.cons], constructors
111 _LIBCPP_HIDE_FROM_ABI flat_multiset() noexcept(is_nothrow_default_constructible_v<_KeyContainer> &&
112 is_nothrow_default_constructible_v<_Compare>)
98 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset() noexcept(
99 is_nothrow_default_constructible_v<_KeyContainer> && is_nothrow_default_constructible_v<_Compare>)
113100 : __keys_(), __compare_() {}
114101
115 _LIBCPP_HIDE_FROM_ABI flat_multiset(const flat_multiset&) = default;
102 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(const flat_multiset&) = default;
116103
117104 // The copy/move constructors are not specified in the spec, which means they should be defaulted.
118105 // However, the move constructor can potentially leave a moved-from object in an inconsistent
119106 // state if an exception is thrown.
120 _LIBCPP_HIDE_FROM_ABI flat_multiset(flat_multiset&& __other) noexcept(
107 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(flat_multiset&& __other) noexcept(
121108 is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_Compare>)
122109# if _LIBCPP_HAS_EXCEPTIONS
123110 try
......@@ -134,14 +121,16 @@ public:
134121# endif // _LIBCPP_HAS_EXCEPTIONS
135122 }
136123
137 _LIBCPP_HIDE_FROM_ABI explicit flat_multiset(const key_compare& __comp) : __keys_(), __compare_(__comp) {}
124 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_multiset(const key_compare& __comp)
125 : __keys_(), __compare_(__comp) {}
138126
139 _LIBCPP_HIDE_FROM_ABI explicit flat_multiset(container_type __keys, const key_compare& __comp = key_compare())
127 _LIBCPP_HIDE_FROM_ABI
128 _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_multiset(container_type __keys, const key_compare& __comp = key_compare())
140129 : __keys_(std::move(__keys)), __compare_(__comp) {
141130 ranges::sort(__keys_, __compare_);
142131 }
143132
144 _LIBCPP_HIDE_FROM_ABI
133 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
145134 flat_multiset(sorted_equivalent_t, container_type __keys, const key_compare& __comp = key_compare())
146135 : __keys_(std::move(__keys)), __compare_(__comp) {
147136 _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(ranges::is_sorted(__keys_, __compare_), "Key container is not sorted");
......@@ -149,7 +138,7 @@ public:
149138
150139 template <class _InputIterator>
151140 requires __has_input_iterator_category<_InputIterator>::value
152 _LIBCPP_HIDE_FROM_ABI
141 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
153142 flat_multiset(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare())
154143 : __keys_(), __compare_(__comp) {
155144 insert(__first, __last);
......@@ -157,48 +146,53 @@ public:
157146
158147 template <class _InputIterator>
159148 requires __has_input_iterator_category<_InputIterator>::value
160 _LIBCPP_HIDE_FROM_ABI flat_multiset(
149 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(
161150 sorted_equivalent_t, _InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare())
162151 : __keys_(__first, __last), __compare_(__comp) {
163152 _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(ranges::is_sorted(__keys_, __compare_), "Key container is not sorted");
164153 }
165154
166155 template <_ContainerCompatibleRange<value_type> _Range>
167 _LIBCPP_HIDE_FROM_ABI flat_multiset(from_range_t __fr, _Range&& __rg)
156 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(from_range_t __fr, _Range&& __rg)
168157 : flat_multiset(__fr, std::forward<_Range>(__rg), key_compare()) {}
169158
170159 template <_ContainerCompatibleRange<value_type> _Range>
171 _LIBCPP_HIDE_FROM_ABI flat_multiset(from_range_t, _Range&& __rg, const key_compare& __comp) : flat_multiset(__comp) {
160 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
161 flat_multiset(from_range_t, _Range&& __rg, const key_compare& __comp)
162 : flat_multiset(__comp) {
172163 insert_range(std::forward<_Range>(__rg));
173164 }
174165
175 _LIBCPP_HIDE_FROM_ABI flat_multiset(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
166 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
167 flat_multiset(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
176168 : flat_multiset(__il.begin(), __il.end(), __comp) {}
177169
178 _LIBCPP_HIDE_FROM_ABI
170 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
179171 flat_multiset(sorted_equivalent_t, initializer_list<value_type> __il, const key_compare& __comp = key_compare())
180172 : flat_multiset(sorted_equivalent, __il.begin(), __il.end(), __comp) {}
181173
182174 template <class _Allocator>
183175 requires uses_allocator<container_type, _Allocator>::value
184 _LIBCPP_HIDE_FROM_ABI explicit flat_multiset(const _Allocator& __alloc)
176 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_multiset(const _Allocator& __alloc)
185177 : __keys_(std::make_obj_using_allocator<container_type>(__alloc)), __compare_() {}
186178
187179 template <class _Allocator>
188180 requires uses_allocator<container_type, _Allocator>::value
189 _LIBCPP_HIDE_FROM_ABI flat_multiset(const key_compare& __comp, const _Allocator& __alloc)
181 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
182 flat_multiset(const key_compare& __comp, const _Allocator& __alloc)
190183 : __keys_(std::make_obj_using_allocator<container_type>(__alloc)), __compare_(__comp) {}
191184
192185 template <class _Allocator>
193186 requires uses_allocator<container_type, _Allocator>::value
194 _LIBCPP_HIDE_FROM_ABI flat_multiset(const container_type& __keys, const _Allocator& __alloc)
187 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
188 flat_multiset(const container_type& __keys, const _Allocator& __alloc)
195189 : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __keys)), __compare_() {
196190 ranges::sort(__keys_, __compare_);
197191 }
198192
199193 template <class _Allocator>
200194 requires uses_allocator<container_type, _Allocator>::value
201 _LIBCPP_HIDE_FROM_ABI
195 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
202196 flat_multiset(const container_type& __keys, const key_compare& __comp, const _Allocator& __alloc)
203197 : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __keys)), __compare_(__comp) {
204198 ranges::sort(__keys_, __compare_);
......@@ -206,14 +200,15 @@ public:
206200
207201 template <class _Allocator>
208202 requires uses_allocator<container_type, _Allocator>::value
209 _LIBCPP_HIDE_FROM_ABI flat_multiset(sorted_equivalent_t, const container_type& __keys, const _Allocator& __alloc)
203 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
204 flat_multiset(sorted_equivalent_t, const container_type& __keys, const _Allocator& __alloc)
210205 : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __keys)), __compare_() {
211206 _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(ranges::is_sorted(__keys_, __compare_), "Key container is not sorted");
212207 }
213208
214209 template <class _Allocator>
215210 requires uses_allocator<container_type, _Allocator>::value
216 _LIBCPP_HIDE_FROM_ABI
211 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
217212 flat_multiset(sorted_equivalent_t, const container_type& __keys, const key_compare& __comp, const _Allocator& __alloc)
218213 : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __keys)), __compare_(__comp) {
219214 _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(ranges::is_sorted(__keys_, __compare_), "Key container is not sorted");
......@@ -221,13 +216,14 @@ public:
221216
222217 template <class _Allocator>
223218 requires uses_allocator<container_type, _Allocator>::value
224 _LIBCPP_HIDE_FROM_ABI flat_multiset(const flat_multiset& __other, const _Allocator& __alloc)
219 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
220 flat_multiset(const flat_multiset& __other, const _Allocator& __alloc)
225221 : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __other.__keys_)),
226222 __compare_(__other.__compare_) {}
227223
228224 template <class _Allocator>
229225 requires uses_allocator<container_type, _Allocator>::value
230 _LIBCPP_HIDE_FROM_ABI flat_multiset(flat_multiset&& __other, const _Allocator& __alloc)
226 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(flat_multiset&& __other, const _Allocator& __alloc)
231227# if _LIBCPP_HAS_EXCEPTIONS
232228 try
233229# endif // _LIBCPP_HAS_EXCEPTIONS
......@@ -243,14 +239,15 @@ public:
243239
244240 template <class _InputIterator, class _Allocator>
245241 requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type, _Allocator>::value)
246 _LIBCPP_HIDE_FROM_ABI flat_multiset(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc)
242 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
243 flat_multiset(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc)
247244 : __keys_(std::make_obj_using_allocator<container_type>(__alloc)), __compare_() {
248245 insert(__first, __last);
249246 }
250247
251248 template <class _InputIterator, class _Allocator>
252249 requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type, _Allocator>::value)
253 _LIBCPP_HIDE_FROM_ABI
250 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
254251 flat_multiset(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc)
255252 : __keys_(std::make_obj_using_allocator<container_type>(__alloc)), __compare_(__comp) {
256253 insert(__first, __last);
......@@ -258,7 +255,7 @@ public:
258255
259256 template <class _InputIterator, class _Allocator>
260257 requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type, _Allocator>::value)
261 _LIBCPP_HIDE_FROM_ABI
258 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
262259 flat_multiset(sorted_equivalent_t, _InputIterator __first, _InputIterator __last, const _Allocator& __alloc)
263260 : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __first, __last)), __compare_() {
264261 _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(ranges::is_sorted(__keys_, __compare_), "Key container is not sorted");
......@@ -266,53 +263,57 @@ public:
266263
267264 template <class _InputIterator, class _Allocator>
268265 requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type, _Allocator>::value)
269 _LIBCPP_HIDE_FROM_ABI
270 flat_multiset(sorted_equivalent_t,
271 _InputIterator __first,
272 _InputIterator __last,
273 const key_compare& __comp,
274 const _Allocator& __alloc)
266 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(
267 sorted_equivalent_t,
268 _InputIterator __first,
269 _InputIterator __last,
270 const key_compare& __comp,
271 const _Allocator& __alloc)
275272 : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __first, __last)), __compare_(__comp) {
276273 _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(ranges::is_sorted(__keys_, __compare_), "Key container is not sorted");
277274 }
278275
279276 template <_ContainerCompatibleRange<value_type> _Range, class _Allocator>
280277 requires uses_allocator<container_type, _Allocator>::value
281 _LIBCPP_HIDE_FROM_ABI flat_multiset(from_range_t, _Range&& __rg, const _Allocator& __alloc)
278 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
279 flat_multiset(from_range_t, _Range&& __rg, const _Allocator& __alloc)
282280 : __keys_(std::make_obj_using_allocator<container_type>(__alloc)), __compare_() {
283281 insert_range(std::forward<_Range>(__rg));
284282 }
285283
286284 template <_ContainerCompatibleRange<value_type> _Range, class _Allocator>
287285 requires uses_allocator<container_type, _Allocator>::value
288 _LIBCPP_HIDE_FROM_ABI flat_multiset(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc)
286 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
287 flat_multiset(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc)
289288 : __keys_(std::make_obj_using_allocator<container_type>(__alloc)), __compare_(__comp) {
290289 insert_range(std::forward<_Range>(__rg));
291290 }
292291
293292 template <class _Allocator>
294293 requires uses_allocator<container_type, _Allocator>::value
295 _LIBCPP_HIDE_FROM_ABI flat_multiset(initializer_list<value_type> __il, const _Allocator& __alloc)
294 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
295 flat_multiset(initializer_list<value_type> __il, const _Allocator& __alloc)
296296 : flat_multiset(__il.begin(), __il.end(), __alloc) {}
297297
298298 template <class _Allocator>
299299 requires uses_allocator<container_type, _Allocator>::value
300 _LIBCPP_HIDE_FROM_ABI
300 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
301301 flat_multiset(initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc)
302302 : flat_multiset(__il.begin(), __il.end(), __comp, __alloc) {}
303303
304304 template <class _Allocator>
305305 requires uses_allocator<container_type, _Allocator>::value
306 _LIBCPP_HIDE_FROM_ABI flat_multiset(sorted_equivalent_t, initializer_list<value_type> __il, const _Allocator& __alloc)
306 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
307 flat_multiset(sorted_equivalent_t, initializer_list<value_type> __il, const _Allocator& __alloc)
307308 : flat_multiset(sorted_equivalent, __il.begin(), __il.end(), __alloc) {}
308309
309310 template <class _Allocator>
310311 requires uses_allocator<container_type, _Allocator>::value
311 _LIBCPP_HIDE_FROM_ABI flat_multiset(
312 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(
312313 sorted_equivalent_t, initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc)
313314 : flat_multiset(sorted_equivalent, __il.begin(), __il.end(), __comp, __alloc) {}
314315
315 _LIBCPP_HIDE_FROM_ABI flat_multiset& operator=(initializer_list<value_type> __il) {
316 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset& operator=(initializer_list<value_type> __il) {
316317 clear();
317318 insert(__il);
318319 return *this;
......@@ -321,9 +322,9 @@ public:
321322 // copy/move assignment are not specified in the spec (defaulted)
322323 // but move assignment can potentially leave moved from object in an inconsistent
323324 // state if an exception is thrown
324 _LIBCPP_HIDE_FROM_ABI flat_multiset& operator=(const flat_multiset&) = default;
325 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset& operator=(const flat_multiset&) = default;
325326
326 _LIBCPP_HIDE_FROM_ABI flat_multiset& operator=(flat_multiset&& __other) noexcept(
327 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset& operator=(flat_multiset&& __other) noexcept(
327328 is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_Compare>) {
328329 auto __clear_other_guard = std::__make_scope_guard([&]() noexcept { __other.clear() /* noexcept */; });
329330 auto __clear_self_guard = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
......@@ -334,30 +335,60 @@ public:
334335 }
335336
336337 // iterators
337 _LIBCPP_HIDE_FROM_ABI iterator begin() noexcept { return iterator(std::as_const(__keys_).begin()); }
338 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { return const_iterator(__keys_.begin()); }
339 _LIBCPP_HIDE_FROM_ABI iterator end() noexcept { return iterator(std::as_const(__keys_).end()); }
340 _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { return const_iterator(__keys_.end()); }
338 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
339 return iterator(std::as_const(__keys_).begin());
340 }
341 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
342 return const_iterator(__keys_.begin());
343 }
344 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
345 return iterator(std::as_const(__keys_).end());
346 }
347 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
348 return const_iterator(__keys_.end());
349 }
341350
342 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
343 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
344 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
345 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
351 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
352 return reverse_iterator(end());
353 }
354 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
355 return const_reverse_iterator(end());
356 }
357 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
358 return reverse_iterator(begin());
359 }
360 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
361 return const_reverse_iterator(begin());
362 }
346363
347 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return begin(); }
348 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return end(); }
349 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
350 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
364 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept {
365 return begin();
366 }
367 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept {
368 return end();
369 }
370 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
371 return const_reverse_iterator(end());
372 }
373 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
374 return const_reverse_iterator(begin());
375 }
351376
352377 // capacity
353 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __keys_.empty(); }
354 _LIBCPP_HIDE_FROM_ABI size_type size() const noexcept { return __keys_.size(); }
355 _LIBCPP_HIDE_FROM_ABI size_type max_size() const noexcept { return __keys_.max_size(); }
378 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool empty() const noexcept {
379 return __keys_.empty();
380 }
381 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
382 return __keys_.size();
383 }
384 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
385 return __keys_.max_size();
386 }
356387
357388 // [flat.multiset.modifiers], modifiers
358389 template <class... _Args>
359390 requires is_constructible_v<value_type, _Args...>
360 _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) {
391 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator emplace(_Args&&... __args) {
361392 if constexpr (sizeof...(__args) == 1 && (is_same_v<remove_cvref_t<_Args>, _Key> && ...)) {
362393 return __emplace(std::forward<_Args>(__args)...);
363394 } else {
......@@ -367,7 +398,7 @@ public:
367398
368399 template <class... _Args>
369400 requires is_constructible_v<value_type, _Args...>
370 _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __hint, _Args&&... __args) {
401 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator emplace_hint(const_iterator __hint, _Args&&... __args) {
371402 if constexpr (sizeof...(__args) == 1 && (is_same_v<remove_cvref_t<_Args>, _Key> && ...)) {
372403 return __emplace_hint(std::move(__hint), std::forward<_Args>(__args)...);
373404 } else {
......@@ -375,21 +406,23 @@ public:
375406 }
376407 }
377408
378 _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __x) { return emplace(__x); }
409 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const value_type& __x) { return emplace(__x); }
379410
380 _LIBCPP_HIDE_FROM_ABI iterator insert(value_type&& __x) { return emplace(std::move(__x)); }
411 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(value_type&& __x) {
412 return emplace(std::move(__x));
413 }
381414
382 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, const value_type& __x) {
415 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, const value_type& __x) {
383416 return emplace_hint(__hint, __x);
384417 }
385418
386 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, value_type&& __x) {
419 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, value_type&& __x) {
387420 return emplace_hint(__hint, std::move(__x));
388421 }
389422
390423 template <class _InputIterator>
391424 requires __has_input_iterator_category<_InputIterator>::value
392 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last) {
425 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(_InputIterator __first, _InputIterator __last) {
393426 if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) {
394427 __reserve(__last - __first);
395428 }
......@@ -398,7 +431,8 @@ public:
398431
399432 template <class _InputIterator>
400433 requires __has_input_iterator_category<_InputIterator>::value
401 _LIBCPP_HIDE_FROM_ABI void insert(sorted_equivalent_t, _InputIterator __first, _InputIterator __last) {
434 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
435 insert(sorted_equivalent_t, _InputIterator __first, _InputIterator __last) {
402436 if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) {
403437 __reserve(__last - __first);
404438 }
......@@ -407,7 +441,7 @@ public:
407441 }
408442
409443 template <_ContainerCompatibleRange<value_type> _Range>
410 _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
444 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(_Range&& __range) {
411445 if constexpr (ranges::sized_range<_Range>) {
412446 __reserve(ranges::size(__range));
413447 }
......@@ -415,26 +449,38 @@ public:
415449 __append_sort_merge</*WasSorted = */ false>(std::forward<_Range>(__range));
416450 }
417451
418 _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
452 template <_ContainerCompatibleRange<value_type> _Range>
453 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(sorted_equivalent_t, _Range&& __range) {
454 if constexpr (ranges::sized_range<_Range>) {
455 __reserve(ranges::size(__range));
456 }
419457
420 _LIBCPP_HIDE_FROM_ABI void insert(sorted_equivalent_t, initializer_list<value_type> __il) {
458 __append_sort_merge</*WasSorted = */ true>(std::forward<_Range>(__range));
459 }
460
461 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(initializer_list<value_type> __il) {
462 insert(__il.begin(), __il.end());
463 }
464
465 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
466 insert(sorted_equivalent_t, initializer_list<value_type> __il) {
421467 insert(sorted_equivalent, __il.begin(), __il.end());
422468 }
423469
424 _LIBCPP_HIDE_FROM_ABI container_type extract() && {
470 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 container_type extract() && {
425471 auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; });
426472 auto __ret = std::move(__keys_);
427473 return __ret;
428474 }
429475
430 _LIBCPP_HIDE_FROM_ABI void replace(container_type&& __keys) {
476 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void replace(container_type&& __keys) {
431477 _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(ranges::is_sorted(__keys, __compare_), "Key container is not sorted");
432478 auto __guard = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
433479 __keys_ = std::move(__keys);
434480 __guard.__complete();
435481 }
436482
437 _LIBCPP_HIDE_FROM_ABI iterator erase(iterator __position) {
483 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(iterator __position) {
438484 auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
439485 auto __key_iter = __keys_.erase(__position.__base());
440486 __on_failure.__complete();
......@@ -444,7 +490,7 @@ public:
444490 // The following overload is the same as the iterator overload
445491 // iterator erase(const_iterator __position);
446492
447 _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __x) {
493 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type erase(const key_type& __x) {
448494 auto [__first, __last] = equal_range(__x);
449495 auto __res = __last - __first;
450496 erase(__first, __last);
......@@ -454,149 +500,170 @@ public:
454500 template <class _Kp>
455501 requires(__is_transparent_v<_Compare> && !is_convertible_v<_Kp &&, iterator> &&
456502 !is_convertible_v<_Kp &&, const_iterator>)
457 _LIBCPP_HIDE_FROM_ABI size_type erase(_Kp&& __x) {
503 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type erase(_Kp&& __x) {
458504 auto [__first, __last] = equal_range(__x);
459505 auto __res = __last - __first;
460506 erase(__first, __last);
461507 return __res;
462508 }
463509
464 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last) {
510 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __first, const_iterator __last) {
465511 auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
466512 auto __key_it = __keys_.erase(__first.__base(), __last.__base());
467513 __on_failure.__complete();
468514 return iterator(std::move(__key_it));
469515 }
470516
471 _LIBCPP_HIDE_FROM_ABI void swap(flat_multiset& __y) noexcept {
472 // warning: The spec has unconditional noexcept, which means that
473 // if any of the following functions throw an exception,
474 // std::terminate will be called
475 // This is discussed in P3567, which hasn't been voted on yet.
517 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
518 swap(flat_multiset& __y) noexcept(is_nothrow_swappable_v<container_type> && is_nothrow_swappable_v<key_compare>) {
519 auto __on_failure = std::__make_exception_guard([&]() noexcept {
520 clear() /* noexcept */;
521 __y.clear() /* noexcept */;
522 });
476523 ranges::swap(__compare_, __y.__compare_);
477524 ranges::swap(__keys_, __y.__keys_);
525 __on_failure.__complete();
478526 }
479527
480 _LIBCPP_HIDE_FROM_ABI void clear() noexcept { __keys_.clear(); }
528 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { __keys_.clear(); }
481529
482530 // observers
483 _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __compare_; }
484 _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return __compare_; }
531 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
532 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
533 return __compare_;
534 }
485535
486536 // map operations
487 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __x) { return __find_impl(*this, __x); }
537 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
538 return __find_impl(*this, __x);
539 }
488540
489 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __x) const { return __find_impl(*this, __x); }
541 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
542 return __find_impl(*this, __x);
543 }
490544
491545 template <class _Kp>
492546 requires __is_transparent_v<_Compare>
493 _LIBCPP_HIDE_FROM_ABI iterator find(const _Kp& __x) {
547 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
494548 return __find_impl(*this, __x);
495549 }
496550
497551 template <class _Kp>
498552 requires __is_transparent_v<_Compare>
499 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Kp& __x) const {
553 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
500554 return __find_impl(*this, __x);
501555 }
502556
503 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __x) const {
557 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
504558 auto [__first, __last] = equal_range(__x);
505559 return __last - __first;
506560 }
507561
508562 template <class _Kp>
509563 requires __is_transparent_v<_Compare>
510 _LIBCPP_HIDE_FROM_ABI size_type count(const _Kp& __x) const {
564 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
511565 auto [__first, __last] = equal_range(__x);
512566 return __last - __first;
513567 }
514568
515 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __x) const { return find(__x) != end(); }
569 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
570 return find(__x) != end();
571 }
516572
517573 template <class _Kp>
518574 requires __is_transparent_v<_Compare>
519 _LIBCPP_HIDE_FROM_ABI bool contains(const _Kp& __x) const {
575 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
520576 return find(__x) != end();
521577 }
522578
523 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __x) {
579 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
524580 const auto& __keys = __keys_;
525581 return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_));
526582 }
527583
528 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __x) const {
584 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
585 lower_bound(const key_type& __x) const {
529586 return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
530587 }
531588
532589 template <class _Kp>
533590 requires __is_transparent_v<_Compare>
534 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _Kp& __x) {
591 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
535592 const auto& __keys = __keys_;
536593 return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_));
537594 }
538595
539596 template <class _Kp>
540597 requires __is_transparent_v<_Compare>
541 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _Kp& __x) const {
598 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
542599 return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
543600 }
544601
545 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __x) {
602 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
546603 const auto& __keys = __keys_;
547604 return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_));
548605 }
549606
550 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __x) const {
607 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
608 upper_bound(const key_type& __x) const {
551609 return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
552610 }
553611
554612 template <class _Kp>
555613 requires __is_transparent_v<_Compare>
556 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _Kp& __x) {
614 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
557615 const auto& __keys = __keys_;
558616 return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_));
559617 }
560618
561619 template <class _Kp>
562620 requires __is_transparent_v<_Compare>
563 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _Kp& __x) const {
621 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
564622 return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
565623 }
566624
567 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __x) {
625 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
626 equal_range(const key_type& __x) {
568627 return __equal_range_impl(*this, __x);
569628 }
570629
571 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __x) const {
630 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
631 equal_range(const key_type& __x) const {
572632 return __equal_range_impl(*this, __x);
573633 }
574634
575635 template <class _Kp>
576636 requires __is_transparent_v<_Compare>
577 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _Kp& __x) {
637 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
638 equal_range(const _Kp& __x) {
578639 return __equal_range_impl(*this, __x);
579640 }
580641 template <class _Kp>
581642 requires __is_transparent_v<_Compare>
582 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _Kp& __x) const {
643 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
644 equal_range(const _Kp& __x) const {
583645 return __equal_range_impl(*this, __x);
584646 }
585647
586 friend _LIBCPP_HIDE_FROM_ABI bool operator==(const flat_multiset& __x, const flat_multiset& __y) {
648 friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
649 operator==(const flat_multiset& __x, const flat_multiset& __y) {
587650 return ranges::equal(__x, __y);
588651 }
589652
590 friend _LIBCPP_HIDE_FROM_ABI auto operator<=>(const flat_multiset& __x, const flat_multiset& __y) {
653 friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 auto
654 operator<=>(const flat_multiset& __x, const flat_multiset& __y) {
591655 return std::lexicographical_compare_three_way(
592656 __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
593657 }
594658
595 friend _LIBCPP_HIDE_FROM_ABI void swap(flat_multiset& __x, flat_multiset& __y) noexcept { __x.swap(__y); }
659 friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
660 swap(flat_multiset& __x, flat_multiset& __y) noexcept(noexcept(__x.swap(__y))) {
661 __x.swap(__y);
662 }
596663
597664private:
598665 template <bool _WasSorted, class... _Args>
599 _LIBCPP_HIDE_FROM_ABI void __append_sort_merge(_Args&&... __args) {
666 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __append_sort_merge(_Args&&... __args) {
600667 auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
601668 size_type __old_size = size();
602669 __flat_set_utils::__append(*this, std::forward<_Args>(__args)...);
......@@ -604,20 +671,20 @@ private:
604671 ranges::sort(__keys_.begin() + __old_size, __keys_.end(), __compare_);
605672 } else {
606673 _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
607 ranges::is_sorted(__keys_ | ranges::views::drop(__old_size)), "Key container is not sorted");
674 ranges::is_sorted(__keys_ | ranges::views::drop(__old_size), __compare_), "Key container is not sorted");
608675 }
609676 ranges::inplace_merge(__keys_.begin(), __keys_.begin() + __old_size, __keys_.end(), __compare_);
610677 __on_failure.__complete();
611678 }
612679
613680 template <class _Kp>
614 _LIBCPP_HIDE_FROM_ABI iterator __emplace(_Kp&& __key) {
681 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __emplace(_Kp&& __key) {
615682 auto __it = upper_bound(__key);
616683 return __flat_set_utils::__emplace_exact_pos(*this, __it, std::forward<_Kp>(__key));
617684 }
618685
619686 template <class _Kp>
620 _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint(const_iterator __hint, _Kp&& __key) {
687 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __emplace_hint(const_iterator __hint, _Kp&& __key) {
621688 auto __prev_larger = __hint != cbegin() && __compare_(__key, *std::prev(__hint));
622689 auto __next_smaller = __hint != cend() && __compare_(*__hint, __key);
623690
......@@ -649,7 +716,7 @@ private:
649716 }
650717
651718 template <class _Self, class _Kp>
652 _LIBCPP_HIDE_FROM_ABI static auto __find_impl(_Self&& __self, const _Kp& __key) {
719 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __find_impl(_Self&& __self, const _Kp& __key) {
653720 auto __it = __self.lower_bound(__key);
654721 auto __last = __self.end();
655722 if (__it == __last || __self.__compare_(__key, *__it)) {
......@@ -659,29 +726,30 @@ private:
659726 }
660727
661728 template <class _Self, class _Kp>
662 _LIBCPP_HIDE_FROM_ABI static auto __equal_range_impl(_Self&& __self, const _Kp& __key) {
729 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __equal_range_impl(_Self&& __self, const _Kp& __key) {
663730 using __iter = _If<is_const_v<__libcpp_remove_reference_t<_Self>>, const_iterator, iterator>;
664731 auto [__key_first, __key_last] =
665732 std::equal_range(__self.__keys_.begin(), __self.__keys_.end(), __key, __self.__compare_);
666733 return std::make_pair(__iter(__key_first), __iter(__key_last));
667734 }
668735
669 _LIBCPP_HIDE_FROM_ABI void __reserve(size_t __size) {
736 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __reserve(size_t __size) {
670737 if constexpr (__container_traits<_KeyContainer>::__reservable) {
671738 __keys_.reserve(__size);
672739 }
673740 }
674741
675742 template <class _Key2, class _Compare2, class _KeyContainer2, class _Predicate>
676 friend typename flat_multiset<_Key2, _Compare2, _KeyContainer2>::size_type
743 friend typename flat_multiset<_Key2, _Compare2, _KeyContainer2>::size_type _LIBCPP_CONSTEXPR_SINCE_CXX26
677744 erase_if(flat_multiset<_Key2, _Compare2, _KeyContainer2>&, _Predicate);
678745
679746 _KeyContainer __keys_;
680747 _LIBCPP_NO_UNIQUE_ADDRESS key_compare __compare_;
681748
682749 struct __key_equiv {
683 _LIBCPP_HIDE_FROM_ABI __key_equiv(key_compare __c) : __comp_(__c) {}
684 _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const {
750 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_equiv(key_compare __c) : __comp_(__c) {}
751 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
752 operator()(const_reference __x, const_reference __y) const {
685753 return !__comp_(std::get<0>(__x), std::get<0>(__y)) && !__comp_(std::get<0>(__y), std::get<0>(__x));
686754 }
687755 key_compare __comp_;
......@@ -689,7 +757,7 @@ private:
689757};
690758
691759template <class _KeyContainer, class _Compare = less<typename _KeyContainer::value_type>>
692 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
760 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> &&
693761 is_invocable_v<const _Compare&,
694762 const typename _KeyContainer::value_type&,
695763 const typename _KeyContainer::value_type&>)
......@@ -697,12 +765,12 @@ flat_multiset(_KeyContainer, _Compare = _Compare())
697765 -> flat_multiset<typename _KeyContainer::value_type, _Compare, _KeyContainer>;
698766
699767template <class _KeyContainer, class _Allocator>
700 requires(uses_allocator_v<_KeyContainer, _Allocator> && !__is_allocator<_KeyContainer>::value)
768 requires(uses_allocator_v<_KeyContainer, _Allocator> && !__is_allocator_v<_KeyContainer>)
701769flat_multiset(_KeyContainer, _Allocator)
702770 -> flat_multiset<typename _KeyContainer::value_type, less<typename _KeyContainer::value_type>, _KeyContainer>;
703771
704772template <class _KeyContainer, class _Compare, class _Allocator>
705 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
773 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> &&
706774 uses_allocator_v<_KeyContainer, _Allocator> &&
707775 is_invocable_v<const _Compare&,
708776 const typename _KeyContainer::value_type&,
......@@ -711,7 +779,7 @@ flat_multiset(_KeyContainer, _Compare, _Allocator)
711779 -> flat_multiset<typename _KeyContainer::value_type, _Compare, _KeyContainer>;
712780
713781template <class _KeyContainer, class _Compare = less<typename _KeyContainer::value_type>>
714 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
782 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> &&
715783 is_invocable_v<const _Compare&,
716784 const typename _KeyContainer::value_type&,
717785 const typename _KeyContainer::value_type&>)
......@@ -719,12 +787,12 @@ flat_multiset(sorted_equivalent_t, _KeyContainer, _Compare = _Compare())
719787 -> flat_multiset<typename _KeyContainer::value_type, _Compare, _KeyContainer>;
720788
721789template <class _KeyContainer, class _Allocator>
722 requires(uses_allocator_v<_KeyContainer, _Allocator> && !__is_allocator<_KeyContainer>::value)
790 requires(uses_allocator_v<_KeyContainer, _Allocator> && !__is_allocator_v<_KeyContainer>)
723791flat_multiset(sorted_equivalent_t, _KeyContainer, _Allocator)
724792 -> flat_multiset<typename _KeyContainer::value_type, less<typename _KeyContainer::value_type>, _KeyContainer>;
725793
726794template <class _KeyContainer, class _Compare, class _Allocator>
727 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
795 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> &&
728796 uses_allocator_v<_KeyContainer, _Allocator> &&
729797 is_invocable_v<const _Compare&,
730798 const typename _KeyContainer::value_type&,
......@@ -732,37 +800,37 @@ template <class _KeyContainer, class _Compare, class _Allocator>
732800flat_multiset(sorted_equivalent_t, _KeyContainer, _Compare, _Allocator)
733801 -> flat_multiset<typename _KeyContainer::value_type, _Compare, _KeyContainer>;
734802
735template <class _InputIterator, class _Compare = less<__iter_value_type<_InputIterator>>>
736 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value)
803template <class _InputIterator, class _Compare = less<__iterator_value_type<_InputIterator>>>
804 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator_v<_Compare>)
737805flat_multiset(_InputIterator, _InputIterator, _Compare = _Compare())
738 -> flat_multiset<__iter_value_type<_InputIterator>, _Compare>;
806 -> flat_multiset<__iterator_value_type<_InputIterator>, _Compare>;
739807
740template <class _InputIterator, class _Compare = less<__iter_value_type<_InputIterator>>>
741 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value)
808template <class _InputIterator, class _Compare = less<__iterator_value_type<_InputIterator>>>
809 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator_v<_Compare>)
742810flat_multiset(sorted_equivalent_t, _InputIterator, _InputIterator, _Compare = _Compare())
743 -> flat_multiset<__iter_value_type<_InputIterator>, _Compare>;
811 -> flat_multiset<__iterator_value_type<_InputIterator>, _Compare>;
744812
745813template <ranges::input_range _Range,
746814 class _Compare = less<ranges::range_value_t<_Range>>,
747815 class _Allocator = allocator<ranges::range_value_t<_Range>>,
748 class = __enable_if_t<!__is_allocator<_Compare>::value && __is_allocator<_Allocator>::value>>
816 class = __enable_if_t<!__is_allocator_v<_Compare> && __is_allocator_v<_Allocator>>>
749817flat_multiset(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) -> flat_multiset<
750818 ranges::range_value_t<_Range>,
751819 _Compare,
752820 vector<ranges::range_value_t<_Range>, __allocator_traits_rebind_t<_Allocator, ranges::range_value_t<_Range>>>>;
753821
754template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator<_Allocator>::value>>
822template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator_v<_Allocator>>>
755823flat_multiset(from_range_t, _Range&&, _Allocator) -> flat_multiset<
756824 ranges::range_value_t<_Range>,
757825 less<ranges::range_value_t<_Range>>,
758826 vector<ranges::range_value_t<_Range>, __allocator_traits_rebind_t<_Allocator, ranges::range_value_t<_Range>>>>;
759827
760828template <class _Key, class _Compare = less<_Key>>
761 requires(!__is_allocator<_Compare>::value)
829 requires(!__is_allocator_v<_Compare>)
762830flat_multiset(initializer_list<_Key>, _Compare = _Compare()) -> flat_multiset<_Key, _Compare>;
763831
764832template <class _Key, class _Compare = less<_Key>>
765 requires(!__is_allocator<_Compare>::value)
833 requires(!__is_allocator_v<_Compare>)
766834flat_multiset(sorted_equivalent_t, initializer_list<_Key>, _Compare = _Compare()) -> flat_multiset<_Key, _Compare>;
767835
768836template <class _Key, class _Compare, class _KeyContainer, class _Allocator>
......@@ -770,7 +838,7 @@ struct uses_allocator<flat_multiset<_Key, _Compare, _KeyContainer>, _Allocator>
770838 : bool_constant<uses_allocator_v<_KeyContainer, _Allocator> > {};
771839
772840template <class _Key, class _Compare, class _KeyContainer, class _Predicate>
773_LIBCPP_HIDE_FROM_ABI typename flat_multiset<_Key, _Compare, _KeyContainer>::size_type
841_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 typename flat_multiset<_Key, _Compare, _KeyContainer>::size_type
774842erase_if(flat_multiset<_Key, _Compare, _KeyContainer>& __flat_multiset, _Predicate __pred) {
775843 auto __guard = std::__make_exception_guard([&] { __flat_multiset.clear(); });
776844 auto __it =
lib/libcxx/include/__flat_set/flat_set.h+86-68
......@@ -12,7 +12,6 @@
1212
1313#include <__algorithm/lexicographical_compare_three_way.h>
1414#include <__algorithm/lower_bound.h>
15#include <__algorithm/min.h>
1615#include <__algorithm/ranges_adjacent_find.h>
1716#include <__algorithm/ranges_equal.h>
1817#include <__algorithm/ranges_inplace_merge.h>
......@@ -24,20 +23,16 @@
2423#include <__compare/synth_three_way.h>
2524#include <__concepts/swappable.h>
2625#include <__config>
27#include <__cstddef/ptrdiff_t.h>
2826#include <__flat_map/sorted_unique.h>
2927#include <__flat_set/ra_iterator.h>
3028#include <__flat_set/utils.h>
31#include <__functional/invoke.h>
3229#include <__functional/is_transparent.h>
3330#include <__functional/operations.h>
3431#include <__fwd/vector.h>
3532#include <__iterator/concepts.h>
36#include <__iterator/distance.h>
3733#include <__iterator/iterator_traits.h>
3834#include <__iterator/next.h>
3935#include <__iterator/prev.h>
40#include <__iterator/ranges_iterator_traits.h>
4136#include <__iterator/reverse_iterator.h>
4237#include <__memory/allocator_traits.h>
4338#include <__memory/uses_allocator.h>
......@@ -47,10 +42,7 @@
4742#include <__ranges/container_compatible_range.h>
4843#include <__ranges/drop_view.h>
4944#include <__ranges/from_range.h>
50#include <__ranges/ref_view.h>
5145#include <__ranges/size.h>
52#include <__ranges/subrange.h>
53#include <__type_traits/conjunction.h>
5446#include <__type_traits/container_traits.h>
5547#include <__type_traits/invoke.h>
5648#include <__type_traits/is_allocator.h>
......@@ -347,38 +339,42 @@ public:
347339 }
348340
349341 // iterators
350 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
342 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
351343 return iterator(std::as_const(__keys_).begin());
352344 }
353 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
345 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
354346 return const_iterator(__keys_.begin());
355347 }
356 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
348 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
357349 return iterator(std::as_const(__keys_).end());
358350 }
359 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
351 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
360352 return const_iterator(__keys_.end());
361353 }
362354
363 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
355 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
364356 return reverse_iterator(end());
365357 }
366 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
358 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
367359 return const_reverse_iterator(end());
368360 }
369 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
361 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
370362 return reverse_iterator(begin());
371363 }
372 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
364 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
373365 return const_reverse_iterator(begin());
374366 }
375367
376 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { return begin(); }
377 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { return end(); }
378 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
368 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept {
369 return begin();
370 }
371 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept {
372 return end();
373 }
374 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
379375 return const_reverse_iterator(end());
380376 }
381 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
377 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
382378 return const_reverse_iterator(begin());
383379 }
384380
......@@ -387,9 +383,13 @@ public:
387383 return __keys_.empty();
388384 }
389385
390 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { return __keys_.size(); }
386 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept {
387 return __keys_.size();
388 }
391389
392 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { return __keys_.max_size(); }
390 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept {
391 return __keys_.max_size();
392 }
393393
394394 // [flat.set.modifiers], modifiers
395395 template <class... _Args>
......@@ -466,6 +466,15 @@ public:
466466 __append_sort_merge_unique</*WasSorted = */ false>(std::forward<_Range>(__range));
467467 }
468468
469 template <_ContainerCompatibleRange<value_type> _Range>
470 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(std::sorted_unique_t, _Range&& __range) {
471 if constexpr (ranges::sized_range<_Range>) {
472 __reserve(ranges::size(__range));
473 }
474
475 __append_sort_merge_unique</*WasSorted = */ true>(std::forward<_Range>(__range));
476 }
477
469478 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(initializer_list<value_type> __il) {
470479 insert(__il.begin(), __il.end());
471480 }
......@@ -474,7 +483,7 @@ public:
474483 insert(sorted_unique, __il.begin(), __il.end());
475484 }
476485
477 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 container_type extract() && {
486 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 container_type extract() && {
478487 auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; });
479488 auto __ret = std::move(__keys_);
480489 return __ret;
......@@ -524,123 +533,131 @@ public:
524533 return iterator(std::move(__key_it));
525534 }
526535
527 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_set& __y) noexcept {
528 // warning: The spec has unconditional noexcept, which means that
529 // if any of the following functions throw an exception,
530 // std::terminate will be called.
531 // This is discussed in P2767, which hasn't been voted on yet.
536 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
537 swap(flat_set& __y) noexcept(is_nothrow_swappable_v<container_type> && is_nothrow_swappable_v<key_compare>) {
538 auto __on_failure = std::__make_exception_guard([&]() noexcept {
539 clear() /* noexcept */;
540 __y.clear() /* noexcept */;
541 });
532542 ranges::swap(__compare_, __y.__compare_);
533543 ranges::swap(__keys_, __y.__keys_);
544 __on_failure.__complete();
534545 }
535546
536547 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { __keys_.clear(); }
537548
538549 // observers
539 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
540 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const { return __compare_; }
550 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
551 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
552 return __compare_;
553 }
541554
542555 // set operations
543 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
556 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
544557 return __find_impl(*this, __x);
545558 }
546559
547 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
560 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
548561 return __find_impl(*this, __x);
549562 }
550563
551564 template <class _Kp>
552565 requires __is_transparent_v<_Compare>
553 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
566 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
554567 return __find_impl(*this, __x);
555568 }
556569
557570 template <class _Kp>
558571 requires __is_transparent_v<_Compare>
559 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
572 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
560573 return __find_impl(*this, __x);
561574 }
562575
563 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
576 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
564577 return contains(__x) ? 1 : 0;
565578 }
566579
567580 template <class _Kp>
568581 requires __is_transparent_v<_Compare>
569 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
582 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
570583 return contains(__x) ? 1 : 0;
571584 }
572585
573 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
586 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
574587 return find(__x) != end();
575588 }
576589
577590 template <class _Kp>
578591 requires __is_transparent_v<_Compare>
579 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
592 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
580593 return find(__x) != end();
581594 }
582595
583 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
596 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
584597 const auto& __keys = __keys_;
585598 return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_));
586599 }
587600
588 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const key_type& __x) const {
601 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
602 lower_bound(const key_type& __x) const {
589603 return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
590604 }
591605
592606 template <class _Kp>
593607 requires __is_transparent_v<_Compare>
594 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
608 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
595609 const auto& __keys = __keys_;
596610 return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_));
597611 }
598612
599613 template <class _Kp>
600614 requires __is_transparent_v<_Compare>
601 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
615 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
602616 return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
603617 }
604618
605 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
619 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
606620 const auto& __keys = __keys_;
607621 return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_));
608622 }
609623
610 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const key_type& __x) const {
624 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
625 upper_bound(const key_type& __x) const {
611626 return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
612627 }
613628
614629 template <class _Kp>
615630 requires __is_transparent_v<_Compare>
616 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
631 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
617632 const auto& __keys = __keys_;
618633 return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_));
619634 }
620635
621636 template <class _Kp>
622637 requires __is_transparent_v<_Compare>
623 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
638 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
624639 return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
625640 }
626641
627 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const key_type& __x) {
642 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
643 equal_range(const key_type& __x) {
628644 return __equal_range_impl(*this, __x);
629645 }
630646
631 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
647 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
632648 equal_range(const key_type& __x) const {
633649 return __equal_range_impl(*this, __x);
634650 }
635651
636652 template <class _Kp>
637653 requires __is_transparent_v<_Compare>
638 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const _Kp& __x) {
654 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator>
655 equal_range(const _Kp& __x) {
639656 return __equal_range_impl(*this, __x);
640657 }
641658 template <class _Kp>
642659 requires __is_transparent_v<_Compare>
643 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
660 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
644661 equal_range(const _Kp& __x) const {
645662 return __equal_range_impl(*this, __x);
646663 }
......@@ -655,13 +672,14 @@ public:
655672 __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
656673 }
657674
658 friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_set& __x, flat_set& __y) noexcept {
675 friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
676 swap(flat_set& __x, flat_set& __y) noexcept(noexcept(__x.swap(__y))) {
659677 __x.swap(__y);
660678 }
661679
662680private:
663681 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_sorted_and_unique(auto&& __key_container) const {
664 auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) { return !__compare_(__x, __y); };
682 auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) -> bool { return !__compare_(__x, __y); };
665683 return ranges::adjacent_find(__key_container, __greater_or_equal_to) == ranges::end(__key_container);
666684 }
667685
......@@ -774,19 +792,19 @@ private:
774792};
775793
776794template <class _KeyContainer, class _Compare = less<typename _KeyContainer::value_type>>
777 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
795 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> &&
778796 is_invocable_v<const _Compare&,
779797 const typename _KeyContainer::value_type&,
780798 const typename _KeyContainer::value_type&>)
781799flat_set(_KeyContainer, _Compare = _Compare()) -> flat_set<typename _KeyContainer::value_type, _Compare, _KeyContainer>;
782800
783801template <class _KeyContainer, class _Allocator>
784 requires(uses_allocator_v<_KeyContainer, _Allocator> && !__is_allocator<_KeyContainer>::value)
802 requires(uses_allocator_v<_KeyContainer, _Allocator> && !__is_allocator_v<_KeyContainer>)
785803flat_set(_KeyContainer, _Allocator)
786804 -> flat_set<typename _KeyContainer::value_type, less<typename _KeyContainer::value_type>, _KeyContainer>;
787805
788806template <class _KeyContainer, class _Compare, class _Allocator>
789 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
807 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> &&
790808 uses_allocator_v<_KeyContainer, _Allocator> &&
791809 is_invocable_v<const _Compare&,
792810 const typename _KeyContainer::value_type&,
......@@ -794,7 +812,7 @@ template <class _KeyContainer, class _Compare, class _Allocator>
794812flat_set(_KeyContainer, _Compare, _Allocator) -> flat_set<typename _KeyContainer::value_type, _Compare, _KeyContainer>;
795813
796814template <class _KeyContainer, class _Compare = less<typename _KeyContainer::value_type>>
797 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
815 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> &&
798816 is_invocable_v<const _Compare&,
799817 const typename _KeyContainer::value_type&,
800818 const typename _KeyContainer::value_type&>)
......@@ -802,12 +820,12 @@ flat_set(sorted_unique_t, _KeyContainer, _Compare = _Compare())
802820 -> flat_set<typename _KeyContainer::value_type, _Compare, _KeyContainer>;
803821
804822template <class _KeyContainer, class _Allocator>
805 requires(uses_allocator_v<_KeyContainer, _Allocator> && !__is_allocator<_KeyContainer>::value)
823 requires(uses_allocator_v<_KeyContainer, _Allocator> && !__is_allocator_v<_KeyContainer>)
806824flat_set(sorted_unique_t, _KeyContainer, _Allocator)
807825 -> flat_set<typename _KeyContainer::value_type, less<typename _KeyContainer::value_type>, _KeyContainer>;
808826
809827template <class _KeyContainer, class _Compare, class _Allocator>
810 requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
828 requires(!__is_allocator_v<_Compare> && !__is_allocator_v<_KeyContainer> &&
811829 uses_allocator_v<_KeyContainer, _Allocator> &&
812830 is_invocable_v<const _Compare&,
813831 const typename _KeyContainer::value_type&,
......@@ -815,37 +833,37 @@ template <class _KeyContainer, class _Compare, class _Allocator>
815833flat_set(sorted_unique_t, _KeyContainer, _Compare, _Allocator)
816834 -> flat_set<typename _KeyContainer::value_type, _Compare, _KeyContainer>;
817835
818template <class _InputIterator, class _Compare = less<__iter_value_type<_InputIterator>>>
819 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value)
836template <class _InputIterator, class _Compare = less<__iterator_value_type<_InputIterator>>>
837 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator_v<_Compare>)
820838flat_set(_InputIterator, _InputIterator, _Compare = _Compare())
821 -> flat_set<__iter_value_type<_InputIterator>, _Compare>;
839 -> flat_set<__iterator_value_type<_InputIterator>, _Compare>;
822840
823template <class _InputIterator, class _Compare = less<__iter_value_type<_InputIterator>>>
824 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value)
841template <class _InputIterator, class _Compare = less<__iterator_value_type<_InputIterator>>>
842 requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator_v<_Compare>)
825843flat_set(sorted_unique_t, _InputIterator, _InputIterator, _Compare = _Compare())
826 -> flat_set<__iter_value_type<_InputIterator>, _Compare>;
844 -> flat_set<__iterator_value_type<_InputIterator>, _Compare>;
827845
828846template <ranges::input_range _Range,
829847 class _Compare = less<ranges::range_value_t<_Range>>,
830848 class _Allocator = allocator<ranges::range_value_t<_Range>>,
831 class = __enable_if_t<!__is_allocator<_Compare>::value && __is_allocator<_Allocator>::value>>
849 class = __enable_if_t<!__is_allocator_v<_Compare> && __is_allocator_v<_Allocator>>>
832850flat_set(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) -> flat_set<
833851 ranges::range_value_t<_Range>,
834852 _Compare,
835853 vector<ranges::range_value_t<_Range>, __allocator_traits_rebind_t<_Allocator, ranges::range_value_t<_Range>>>>;
836854
837template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator<_Allocator>::value>>
855template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator_v<_Allocator>>>
838856flat_set(from_range_t, _Range&&, _Allocator) -> flat_set<
839857 ranges::range_value_t<_Range>,
840858 less<ranges::range_value_t<_Range>>,
841859 vector<ranges::range_value_t<_Range>, __allocator_traits_rebind_t<_Allocator, ranges::range_value_t<_Range>>>>;
842860
843861template <class _Key, class _Compare = less<_Key>>
844 requires(!__is_allocator<_Compare>::value)
862 requires(!__is_allocator_v<_Compare>)
845863flat_set(initializer_list<_Key>, _Compare = _Compare()) -> flat_set<_Key, _Compare>;
846864
847865template <class _Key, class _Compare = less<_Key>>
848 requires(!__is_allocator<_Compare>::value)
866 requires(!__is_allocator_v<_Compare>)
849867flat_set(sorted_unique_t, initializer_list<_Key>, _Compare = _Compare()) -> flat_set<_Key, _Compare>;
850868
851869template <class _Key, class _Compare, class _KeyContainer, class _Allocator>
lib/libcxx/include/__format/concepts.h-14
......@@ -15,12 +15,8 @@
1515#include <__config>
1616#include <__format/format_parse_context.h>
1717#include <__fwd/format.h>
18#include <__fwd/tuple.h>
19#include <__tuple/tuple_size.h>
20#include <__type_traits/is_specialization.h>
2118#include <__type_traits/remove_const.h>
2219#include <__type_traits/remove_reference.h>
23#include <__utility/pair.h>
2420
2521#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2622# pragma GCC system_header
......@@ -65,16 +61,6 @@ concept __formattable =
6561# if _LIBCPP_STD_VER >= 23
6662template <class _Tp, class _CharT>
6763concept formattable = __formattable<_Tp, _CharT>;
68
69// [tuple.like] defines a tuple-like exposition only concept. This concept is
70// not related to that. Therefore it uses a different name for the concept.
71//
72// TODO FMT Add a test to validate we fail when using that concept after P2165
73// has been implemented.
74template <class _Tp>
75concept __fmt_pair_like =
76 __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2);
77
7864# endif // _LIBCPP_STD_VER >= 23
7965#endif // _LIBCPP_STD_VER >= 20
8066
lib/libcxx/include/__format/extended_grapheme_cluster_table.h+3-2
......@@ -61,7 +61,7 @@
6161#ifndef _LIBCPP___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H
6262#define _LIBCPP___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H
6363
64#include <__algorithm/ranges_upper_bound.h>
64#include <__algorithm/upper_bound.h>
6565#include <__config>
6666#include <__cstddef/ptrdiff_t.h>
6767#include <__iterator/access.h>
......@@ -1647,7 +1647,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __entries[1501] = {
16471647 // size. Then the upper bound for code point 3 will return the entry after
16481648 // 0x1810. After moving to the previous entry the algorithm arrives at the
16491649 // correct entry.
1650 ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 11) | 0x7ffu) - __entries;
1650 ptrdiff_t __i =
1651 std::upper_bound(std::begin(__entries), std::end(__entries), (__code_point << 11) | 0x7ffu) - __entries;
16511652 if (__i == 0)
16521653 return __property::__none;
16531654
lib/libcxx/include/__format/fmt_pair_like.h created+42
......@@ -0,0 +1,42 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FORMAT_FMT_PAIR_LIKE_H
11#define _LIBCPP___FORMAT_FMT_PAIR_LIKE_H
12
13#include <__config>
14#include <__fwd/pair.h>
15#include <__fwd/tuple.h>
16#include <__tuple/tuple_size.h>
17#include <__type_traits/is_specialization.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#if _LIBCPP_STD_VER >= 23
26
27// [tuple.like] defines a tuple-like exposition only concept. This concept is not related to that. Therefore it uses a
28// different name for the concept.
29//
30// TODO FMT Add a test to validate we fail when using that concept after P2165 has been implemented.
31
32// [format.range.fmtkind]/2.2.1 and [tab:formatter.range.type]:
33// "U is either a specialization of pair or a specialization of tuple such that tuple_size_v<U> is 2."
34template <class _Tp>
35concept __fmt_pair_like =
36 __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2);
37
38#endif // _LIBCPP_STD_VER >= 23
39
40_LIBCPP_END_NAMESPACE_STD
41
42#endif // _LIBCPP___FORMAT_FMT_PAIR_LIKE_H
lib/libcxx/include/__format/format_arg.h+7-10
......@@ -149,7 +149,7 @@ _LIBCPP_HIDE_FROM_ABI decltype(auto) __visit_format_arg(_Visitor&& __vis, basic_
149149 __libcpp_unreachable();
150150}
151151
152# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
152# if _LIBCPP_STD_VER >= 26
153153
154154template <class _Rp, class _Visitor, class _Context>
155155_LIBCPP_HIDE_FROM_ABI _Rp __visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
......@@ -200,7 +200,7 @@ _LIBCPP_HIDE_FROM_ABI _Rp __visit_format_arg(_Visitor&& __vis, basic_format_arg<
200200 __libcpp_unreachable();
201201}
202202
203# endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
203# endif // _LIBCPP_STD_VER >= 26
204204
205205/// Contains the values used in basic_format_arg.
206206///
......@@ -285,7 +285,7 @@ public:
285285
286286 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { return __type_ != __format::__arg_t::__none; }
287287
288# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
288# if _LIBCPP_STD_VER >= 26
289289
290290 // This function is user facing, so it must wrap the non-standard types of
291291 // the "variant" in a handle to stay conforming. See __arg_t for more details.
......@@ -329,7 +329,7 @@ public:
329329 }
330330 }
331331
332# endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
332# endif // _LIBCPP_STD_VER >= 26
333333
334334private:
335335 using char_type = typename _Context::char_type;
......@@ -371,11 +371,8 @@ private:
371371// This function is user facing, so it must wrap the non-standard types of
372372// the "variant" in a handle to stay conforming. See __arg_t for more details.
373373template <class _Visitor, class _Context>
374# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
375_LIBCPP_DEPRECATED_IN_CXX26
376# endif
377 _LIBCPP_HIDE_FROM_ABI decltype(auto)
378 visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
374_LIBCPP_DEPRECATED_IN_CXX26 _LIBCPP_HIDE_FROM_ABI decltype(auto)
375visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
379376 switch (__arg.__type_) {
380377# if _LIBCPP_HAS_INT128
381378 case __format::__arg_t::__i128: {
......@@ -387,7 +384,7 @@ _LIBCPP_DEPRECATED_IN_CXX26
387384 typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__u128_};
388385 return std::invoke(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
389386 }
390# endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
387# endif // _LIBCPP_HAS_INT128
391388 default:
392389 return std::__visit_format_arg(std::forward<_Visitor>(__vis), __arg);
393390 }
lib/libcxx/include/__format/format_args.h+1-1
......@@ -40,7 +40,7 @@ public:
4040 }
4141 }
4242
43 _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> get(size_t __id) const noexcept {
43 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> get(size_t __id) const noexcept {
4444 if (__id >= __size_)
4545 return basic_format_arg<_Context>{};
4646
lib/libcxx/include/__format/format_context.h+5-5
......@@ -80,17 +80,17 @@ public:
8080 template <class _Tp>
8181 using formatter_type = formatter<_Tp, _CharT>;
8282
83 _LIBCPP_HIDE_FROM_ABI basic_format_arg<basic_format_context> arg(size_t __id) const noexcept {
83 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_format_arg<basic_format_context> arg(size_t __id) const noexcept {
8484 return __args_.get(__id);
8585 }
8686# if _LIBCPP_HAS_LOCALIZATION
87 _LIBCPP_HIDE_FROM_ABI std::locale locale() {
87 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI std::locale locale() {
8888 if (!__loc_)
8989 __loc_ = std::locale{};
9090 return *__loc_;
9191 }
9292# endif
93 _LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); }
93 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); }
9494 _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = std::move(__it); }
9595
9696private:
......@@ -175,13 +175,13 @@ public:
175175 __format::__determine_arg_t<basic_format_context, decltype(__arg)>(),
176176 __basic_format_arg_value<basic_format_context>(__arg)};
177177 };
178# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
178# if _LIBCPP_STD_VER >= 26
179179 return static_cast<_Context*>(__c)->arg(__id).visit(std::move(__visitor));
180180# else
181181 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
182182 return std::visit_format_arg(std::move(__visitor), static_cast<_Context*>(__c)->arg(__id));
183183 _LIBCPP_SUPPRESS_DEPRECATED_POP
184# endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
184# endif // _LIBCPP_STD_VER >= 26
185185 }) {
186186 }
187187
lib/libcxx/include/__format/format_parse_context.h+2-2
......@@ -41,8 +41,8 @@ public:
4141 basic_format_parse_context(const basic_format_parse_context&) = delete;
4242 basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;
4343
44 _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept { return __begin_; }
45 _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { return __end_; }
44 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept { return __begin_; }
45 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { return __end_; }
4646 _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(const_iterator __it) { __begin_ = __it; }
4747
4848 _LIBCPP_HIDE_FROM_ABI constexpr size_t next_arg_id() {
lib/libcxx/include/__format/formatter_output.h+30-34
......@@ -45,7 +45,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
4545
4646namespace __formatter {
4747
48struct _LIBCPP_EXPORTED_FROM_ABI __padding_size_result {
48struct __padding_size_result {
4949 size_t __before_;
5050 size_t __after_;
5151};
......@@ -151,45 +151,41 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, _CharT __value)
151151 }
152152}
153153
154# if _LIBCPP_HAS_UNICODE
155154template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
156 requires(same_as<_CharT, char>)
157155_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
158 std::size_t __bytes = std::countl_one(static_cast<unsigned char>(__value.__data[0]));
159 if (__bytes == 0)
160 return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
161
162 for (size_t __i = 0; __i < __n; ++__i)
163 __out_it = __formatter::__copy(
164 std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + __bytes, std::move(__out_it));
165 return __out_it;
166}
167
156# if _LIBCPP_HAS_UNICODE
157 if constexpr (same_as<_CharT, char>) {
158 std::size_t __bytes = std::countl_one(static_cast<unsigned char>(__value.__data[0]));
159 if (__bytes == 0)
160 return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
161
162 for (size_t __i = 0; __i < __n; ++__i)
163 __out_it = __formatter::__copy(
164 std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + __bytes, std::move(__out_it));
165 return __out_it;
168166# if _LIBCPP_HAS_WIDE_CHARACTERS
169template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
170 requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2)
171_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
172 if (!__unicode::__is_high_surrogate(__value.__data[0]))
173 return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
174
175 for (size_t __i = 0; __i < __n; ++__i)
176 __out_it = __formatter::__copy(
177 std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + 2, std::move(__out_it));
178 return __out_it;
179}
180
181template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
182 requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4)
183_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
184 return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
185}
167 } else if constexpr (same_as<_CharT, wchar_t>) {
168 if constexpr (sizeof(wchar_t) == 2) {
169 if (!__unicode::__is_high_surrogate(__value.__data[0]))
170 return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
171
172 for (size_t __i = 0; __i < __n; ++__i)
173 __out_it = __formatter::__copy(
174 std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + 2, std::move(__out_it));
175 return __out_it;
176 } else if constexpr (sizeof(wchar_t) == 4) {
177 return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
178 } else {
179 static_assert(false, "expected sizeof(wchar_t) to be 2 or 4");
180 }
186181# endif // _LIBCPP_HAS_WIDE_CHARACTERS
187# else // _LIBCPP_HAS_UNICODE
188template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
189_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
182 } else {
183 static_assert(false, "Unexpected CharT");
184 }
185# else // _LIBCPP_HAS_UNICODE
190186 return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
187# endif // _LIBCPP_HAS_UNICODE
191188}
192# endif // _LIBCPP_HAS_UNICODE
193189
194190/// Writes the input to the output with the required padding.
195191///
lib/libcxx/include/__format/indic_conjunct_break_table.h+3-2
......@@ -61,7 +61,7 @@
6161#ifndef _LIBCPP___FORMAT_INDIC_CONJUNCT_BREAK_TABLE_H
6262#define _LIBCPP___FORMAT_INDIC_CONJUNCT_BREAK_TABLE_H
6363
64#include <__algorithm/ranges_upper_bound.h>
64#include <__algorithm/upper_bound.h>
6565#include <__config>
6666#include <__cstddef/ptrdiff_t.h>
6767#include <__iterator/access.h>
......@@ -531,7 +531,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __entries[403] = {
531531 // size. Then the upper bound for code point 3 will return the entry after
532532 // 0x1810. After moving to the previous entry the algorithm arrives at the
533533 // correct entry.
534 ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 11) | 0x7ffu) - __entries;
534 ptrdiff_t __i =
535 std::upper_bound(std::begin(__entries), std::end(__entries), (__code_point << 11) | 0x7ffu) - __entries;
535536 if (__i == 0)
536537 return __property::__none;
537538
lib/libcxx/include/__format/range_default_formatter.h+2-41
......@@ -16,10 +16,11 @@
1616
1717#include <__algorithm/ranges_copy.h>
1818#include <__chrono/statically_widen.h>
19#include <__concepts/same_as.h>
2019#include <__config>
2120#include <__format/concepts.h>
21#include <__format/fmt_pair_like.h>
2222#include <__format/formatter.h>
23#include <__format/range_format.h>
2324#include <__format/range_formatter.h>
2425#include <__iterator/back_insert_iterator.h>
2526#include <__ranges/concepts.h>
......@@ -42,51 +43,11 @@ concept __const_formattable_range =
4243template <class _Rp, class _CharT>
4344using __fmt_maybe_const _LIBCPP_NODEBUG = conditional_t<__const_formattable_range<_Rp, _CharT>, const _Rp, _Rp>;
4445
45_LIBCPP_DIAGNOSTIC_PUSH
46_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow")
47_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshadow")
48// This shadows map, set, and string.
49enum class range_format { disabled, map, set, sequence, string, debug_string };
50_LIBCPP_DIAGNOSTIC_POP
51
5246// There is no definition of this struct, it's purely intended to be used to
5347// generate diagnostics.
5448template <class _Rp>
5549struct __instantiated_the_primary_template_of_format_kind;
5650
57template <class _Rp>
58constexpr range_format format_kind = [] {
59 // [format.range.fmtkind]/1
60 // A program that instantiates the primary template of format_kind is ill-formed.
61 static_assert(sizeof(_Rp) != sizeof(_Rp), "create a template specialization of format_kind for your type");
62 return range_format::disabled;
63}();
64
65template <ranges::input_range _Rp>
66 requires same_as<_Rp, remove_cvref_t<_Rp>>
67inline constexpr range_format format_kind<_Rp> = [] {
68 // [format.range.fmtkind]/2
69
70 // 2.1 If same_as<remove_cvref_t<ranges::range_reference_t<R>>, R> is true,
71 // Otherwise format_kind<R> is range_format::disabled.
72 if constexpr (same_as<remove_cvref_t<ranges::range_reference_t<_Rp>>, _Rp>)
73 return range_format::disabled;
74 // 2.2 Otherwise, if the qualified-id R::key_type is valid and denotes a type:
75 else if constexpr (requires { typename _Rp::key_type; }) {
76 // 2.2.1 If the qualified-id R::mapped_type is valid and denotes a type ...
77 if constexpr (requires { typename _Rp::mapped_type; } &&
78 // 2.2.1 ... If either U is a specialization of pair or U is a specialization
79 // of tuple and tuple_size_v<U> == 2
80 __fmt_pair_like<remove_cvref_t<ranges::range_reference_t<_Rp>>>)
81 return range_format::map;
82 else
83 // 2.2.2 Otherwise format_kind<R> is range_format::set.
84 return range_format::set;
85 } else
86 // 2.3 Otherwise, format_kind<R> is range_format::sequence.
87 return range_format::sequence;
88}();
89
9051template <range_format _Kp, ranges::input_range _Rp, class _CharT>
9152struct __range_default_formatter;
9253
lib/libcxx/include/__format/range_format.h created+71
......@@ -0,0 +1,71 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FORMAT_RANGE_FORMAT_H
11#define _LIBCPP___FORMAT_RANGE_FORMAT_H
12
13#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
14# pragma GCC system_header
15#endif
16
17#include <__concepts/same_as.h>
18#include <__config>
19#include <__format/fmt_pair_like.h>
20#include <__ranges/concepts.h>
21#include <__type_traits/remove_cvref.h>
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#if _LIBCPP_STD_VER >= 23
26
27_LIBCPP_DIAGNOSTIC_PUSH
28_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow")
29_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshadow")
30// This shadows map, set, and string.
31enum class range_format { disabled, map, set, sequence, string, debug_string };
32_LIBCPP_DIAGNOSTIC_POP
33
34template <class _Rp>
35constexpr range_format format_kind = [] {
36 // [format.range.fmtkind]/1
37 // A program that instantiates the primary template of format_kind is ill-formed.
38 static_assert(sizeof(_Rp) != sizeof(_Rp), "create a template specialization of format_kind for your type");
39 return range_format::disabled;
40}();
41
42template <ranges::input_range _Rp>
43 requires same_as<_Rp, remove_cvref_t<_Rp>>
44inline constexpr range_format format_kind<_Rp> = [] {
45 // [format.range.fmtkind]/2
46
47 // 2.1 If same_as<remove_cvref_t<ranges::range_reference_t<R>>, R> is true,
48 // Otherwise format_kind<R> is range_format::disabled.
49 if constexpr (same_as<remove_cvref_t<ranges::range_reference_t<_Rp>>, _Rp>)
50 return range_format::disabled;
51 // 2.2 Otherwise, if the qualified-id R::key_type is valid and denotes a type:
52 else if constexpr (requires { typename _Rp::key_type; }) {
53 // 2.2.1 If the qualified-id R::mapped_type is valid and denotes a type ...
54 if constexpr (requires { typename _Rp::mapped_type; } &&
55 // 2.2.1 ... If either U is a specialization of pair or U is a specialization
56 // of tuple and tuple_size_v<U> == 2
57 __fmt_pair_like<remove_cvref_t<ranges::range_reference_t<_Rp>>>)
58 return range_format::map;
59 else
60 // 2.2.2 Otherwise format_kind<R> is range_format::set.
61 return range_format::set;
62 } else
63 // 2.3 Otherwise, format_kind<R> is range_format::sequence.
64 return range_format::sequence;
65}();
66
67#endif // _LIBCPP_STD_VER >= 23
68
69_LIBCPP_END_NAMESPACE_STD
70
71#endif
lib/libcxx/include/__format/range_formatter.h+1
......@@ -20,6 +20,7 @@
2020#include <__config>
2121#include <__format/buffer.h>
2222#include <__format/concepts.h>
23#include <__format/fmt_pair_like.h>
2324#include <__format/format_context.h>
2425#include <__format/format_error.h>
2526#include <__format/formatter.h>
lib/libcxx/include/__format/width_estimation_table.h+4-2
......@@ -61,9 +61,10 @@
6161#ifndef _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H
6262#define _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H
6363
64#include <__algorithm/ranges_upper_bound.h>
64#include <__algorithm/upper_bound.h>
6565#include <__config>
6666#include <__cstddef/ptrdiff_t.h>
67#include <__iterator/access.h>
6768#include <cstdint>
6869
6970#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -255,7 +256,8 @@ inline constexpr uint32_t __table_upper_bound = 0x0003fffd;
255256 if (__code_point < (__entries[0] >> 14))
256257 return 1;
257258
258 ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 14) | 0x3fffu) - __entries;
259 ptrdiff_t __i =
260 std::upper_bound(std::begin(__entries), std::end(__entries), (__code_point << 14) | 0x3fffu) - __entries;
259261 if (__i == 0)
260262 return 1;
261263
lib/libcxx/include/__functional/bind.h+10-15
......@@ -81,17 +81,12 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& __mu(reference_w
8181 return __t.get();
8282}
8383
84template <class _Ti, class... _Uj, size_t... _Indx>
85inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t<_Ti&, _Uj...>
86__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>) {
87 return __ti(std::forward<_Uj>(std::get<_Indx>(__uj))...);
88}
89
9084template <class _Ti, class... _Uj, __enable_if_t<is_bind_expression<_Ti>::value, int> = 0>
9185inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t<_Ti&, _Uj...>
9286__mu(_Ti& __ti, tuple<_Uj...>& __uj) {
93 typedef typename __make_tuple_indices<sizeof...(_Uj)>::type __indices;
94 return std::__mu_expand(__ti, __uj, __indices());
87 return [&]<size_t... _Indices>(__index_sequence<_Indices...>) -> __invoke_result_t<_Ti&, _Uj...> {
88 return __ti(std::forward<_Uj>(std::get<_Indices>(__uj))...);
89 }(__index_sequence_for<_Uj...>{});
9590}
9691
9792template <bool _IsPh, class _Ti, class _Uj>
......@@ -191,7 +186,7 @@ struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true> {
191186
192187template <class _Fp, class _BoundArgs, size_t... _Indx, class _Args>
193188inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bind_return<_Fp, _BoundArgs, _Args>::type
194__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>, _Args&& __args) {
189__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __index_sequence<_Indx...>, _Args&& __args) {
195190 return std::__invoke(__f, std::__mu(std::get<_Indx>(__bound_args), __args)...);
196191}
197192
......@@ -205,8 +200,6 @@ private:
205200 _Fd __f_;
206201 _Td __bound_args_;
207202
208 typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices;
209
210203public:
211204 template <
212205 class _Gp,
......@@ -219,14 +212,16 @@ public:
219212 template <class... _Args>
220213 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type
221214 operator()(_Args&&... __args) {
222 return std::__apply_functor(__f_, __bound_args_, __indices(), tuple<_Args&&...>(std::forward<_Args>(__args)...));
215 return std::__apply_functor(
216 __f_, __bound_args_, __index_sequence_for<_BoundArgs...>(), tuple<_Args&&...>(std::forward<_Args>(__args)...));
223217 }
224218
225219 template <class... _Args>
226220 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
227221 typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type
228222 operator()(_Args&&... __args) const {
229 return std::__apply_functor(__f_, __bound_args_, __indices(), tuple<_Args&&...>(std::forward<_Args>(__args)...));
223 return std::__apply_functor(
224 __f_, __bound_args_, __index_sequence_for<_BoundArgs...>(), tuple<_Args&&...>(std::forward<_Args>(__args)...));
230225 }
231226};
232227
......@@ -273,14 +268,14 @@ template <class _Rp, class _Fp, class... _BoundArgs>
273268struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};
274269
275270template <class _Fp, class... _BoundArgs>
276inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind<_Fp, _BoundArgs...>
271[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind<_Fp, _BoundArgs...>
277272bind(_Fp&& __f, _BoundArgs&&... __bound_args) {
278273 typedef __bind<_Fp, _BoundArgs...> type;
279274 return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...);
280275}
281276
282277template <class _Rp, class _Fp, class... _BoundArgs>
283inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind_r<_Rp, _Fp, _BoundArgs...>
278[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind_r<_Rp, _Fp, _BoundArgs...>
284279bind(_Fp&& __f, _BoundArgs&&... __bound_args) {
285280 typedef __bind_r<_Rp, _Fp, _BoundArgs...> type;
286281 return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...);
lib/libcxx/include/__functional/bind_back.h+1-1
......@@ -64,7 +64,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) n
6464
6565# if _LIBCPP_STD_VER >= 23
6666template <class _Fn, class... _Args>
67_LIBCPP_HIDE_FROM_ABI constexpr auto bind_back(_Fn&& __f, _Args&&... __args) {
67[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto bind_back(_Fn&& __f, _Args&&... __args) {
6868 static_assert(is_constructible_v<decay_t<_Fn>, _Fn>, "bind_back requires decay_t<F> to be constructible from F");
6969 static_assert(is_move_constructible_v<decay_t<_Fn>>, "bind_back requires decay_t<F> to be move constructible");
7070 static_assert((is_constructible_v<decay_t<_Args>, _Args> && ...),
lib/libcxx/include/__functional/bind_front.h+1-1
......@@ -43,7 +43,7 @@ struct __bind_front_t : __perfect_forward<__bind_front_op, _Fn, _BoundArgs...> {
4343template <class _Fn, class... _Args>
4444 requires is_constructible_v<decay_t<_Fn>, _Fn> && is_move_constructible_v<decay_t<_Fn>> &&
4545 (is_constructible_v<decay_t<_Args>, _Args> && ...) && (is_move_constructible_v<decay_t<_Args>> && ...)
46_LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) {
46[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) {
4747 return __bind_front_t<decay_t<_Fn>, decay_t<_Args>...>(std::forward<_Fn>(__f), std::forward<_Args>(__args)...);
4848}
4949
lib/libcxx/include/__functional/function.h+57-75
......@@ -15,16 +15,14 @@
1515#include <__cstddef/nullptr_t.h>
1616#include <__exception/exception.h>
1717#include <__functional/binary_function.h>
18#include <__functional/invoke.h>
1918#include <__functional/unary_function.h>
2019#include <__memory/addressof.h>
2120#include <__type_traits/aligned_storage.h>
2221#include <__type_traits/decay.h>
23#include <__type_traits/is_core_convertible.h>
22#include <__type_traits/invoke.h>
2423#include <__type_traits/is_scalar.h>
2524#include <__type_traits/is_trivially_constructible.h>
2625#include <__type_traits/is_trivially_destructible.h>
27#include <__type_traits/is_void.h>
2826#include <__type_traits/strip_signature.h>
2927#include <__utility/forward.h>
3028#include <__utility/move.h>
......@@ -95,29 +93,29 @@ template <class _Rp, class _A1, class _A2>
9593struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {};
9694
9795template <class _Fp>
98_LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp const&) {
99 return true;
96_LIBCPP_HIDE_FROM_ABI bool __is_null(_Fp const&) {
97 return false;
10098}
10199
102100template <class _Fp>
103_LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp* __ptr) {
104 return __ptr;
101_LIBCPP_HIDE_FROM_ABI bool __is_null(_Fp* __ptr) {
102 return !__ptr;
105103}
106104
107105template <class _Ret, class _Class>
108_LIBCPP_HIDE_FROM_ABI bool __not_null(_Ret _Class::*__ptr) {
109 return __ptr;
106_LIBCPP_HIDE_FROM_ABI bool __is_null(_Ret _Class::* __ptr) {
107 return !__ptr;
110108}
111109
112110template <class _Fp>
113_LIBCPP_HIDE_FROM_ABI bool __not_null(function<_Fp> const& __f) {
114 return !!__f;
111_LIBCPP_HIDE_FROM_ABI bool __is_null(function<_Fp> const& __f) {
112 return !__f;
115113}
116114
117115# if __has_extension(blocks)
118116template <class _Rp, class... _Args>
119_LIBCPP_HIDE_FROM_ABI bool __not_null(_Rp (^__p)(_Args...)) {
120 return __p;
117_LIBCPP_HIDE_FROM_ABI bool __is_null(_Rp (^__p)(_Args...)) {
118 return !__p;
121119}
122120# endif
123121
......@@ -206,12 +204,13 @@ public:
206204 _LIBCPP_HIDE_FROM_ABI explicit __value_func(_Fp&& __f) : __f_(nullptr) {
207205 typedef __function::__func<_Fp, _Rp(_ArgTypes...)> _Fun;
208206
209 if (__function::__not_null(__f)) {
210 if (sizeof(_Fun) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value) {
211 __f_ = ::new (std::addressof(__buf_)) _Fun(std::move(__f));
212 } else {
213 __f_ = new _Fun(std::move(__f));
214 }
207 if (__function::__is_null(__f))
208 return;
209
210 if (sizeof(_Fun) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value) {
211 __f_ = ::new (std::addressof(__buf_)) _Fun(std::move(__f));
212 } else {
213 __f_ = new _Fun(std::move(__f));
215214 }
216215 }
217216
......@@ -356,7 +355,31 @@ struct __policy {
356355 // type.
357356 template <typename _Fun>
358357 _LIBCPP_HIDE_FROM_ABI static const __policy* __create() {
359 return __choose_policy<_Fun>(__use_small_storage<_Fun>());
358 if constexpr (__use_small_storage<_Fun>::value) {
359 static constexpr __policy __policy = {
360 nullptr,
361 nullptr,
362 false,
363# if _LIBCPP_HAS_RTTI
364 &typeid(_Fun)
365# else
366 nullptr
367# endif
368 };
369 return &__policy;
370 } else {
371 static constexpr __policy __policy = {
372 std::addressof(__large_clone<_Fun>),
373 std::addressof(__large_destroy<_Fun>),
374 false,
375# if _LIBCPP_HAS_RTTI
376 &typeid(_Fun)
377# else
378 nullptr
379# endif
380 };
381 return &__policy;
382 }
360383 }
361384
362385 _LIBCPP_HIDE_FROM_ABI static const __policy* __create_empty() {
......@@ -384,36 +407,6 @@ private:
384407 _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) {
385408 delete static_cast<_Fun*>(__s);
386409 }
387
388 template <typename _Fun>
389 _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ false_type) {
390 static constexpr __policy __policy = {
391 std::addressof(__large_clone<_Fun>),
392 std::addressof(__large_destroy<_Fun>),
393 false,
394# if _LIBCPP_HAS_RTTI
395 &typeid(_Fun)
396# else
397 nullptr
398# endif
399 };
400 return &__policy;
401 }
402
403 template <typename _Fun>
404 _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ true_type) {
405 static constexpr __policy __policy = {
406 nullptr,
407 nullptr,
408 false,
409# if _LIBCPP_HAS_RTTI
410 &typeid(_Fun)
411# else
412 nullptr
413# endif
414 };
415 return &__policy;
416 }
417410};
418411
419412// Used to choose between perfect forwarding or pass-by-value. Pass-by-value is
......@@ -455,14 +448,15 @@ public:
455448
456449 template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __policy_func>::value, int> = 0>
457450 _LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f) : __policy_(__policy::__create_empty()) {
458 if (__function::__not_null(__f)) {
459 __func_ = __call_func<_Fp>;
460 __policy_ = __policy::__create<_Fp>();
461 if (__use_small_storage<_Fp>()) {
462 ::new ((void*)&__buf_.__small) _Fp(std::move(__f));
463 } else {
464 __buf_.__large = ::new _Fp(std::move(__f));
465 }
451 if (__function::__is_null(__f))
452 return;
453
454 __func_ = __call_func<_Fp>;
455 __policy_ = __policy::__create<_Fp>();
456 if (__use_small_storage<_Fp>()) {
457 ::new ((void*)&__buf_.__small) _Fp(std::move(__f));
458 } else {
459 __buf_.__large = ::new _Fp(std::move(__f));
466460 }
467461 }
468462
......@@ -615,21 +609,9 @@ class function<_Rp(_ArgTypes...)>
615609
616610 __func __f_;
617611
618 template <class _Fp,
619 bool = _And<_IsNotSame<__remove_cvref_t<_Fp>, function>, __is_invocable<_Fp, _ArgTypes...> >::value>
620 struct __callable;
621 template <class _Fp>
622 struct __callable<_Fp, true> {
623 static const bool value =
624 is_void<_Rp>::value || __is_core_convertible<__invoke_result_t<_Fp, _ArgTypes...>, _Rp>::value;
625 };
626 template <class _Fp>
627 struct __callable<_Fp, false> {
628 static const bool value = false;
629 };
630
631612 template <class _Fp>
632 using _EnableIfLValueCallable _LIBCPP_NODEBUG = __enable_if_t<__callable<_Fp&>::value>;
613 using _EnableIfLValueCallable _LIBCPP_NODEBUG = __enable_if_t<
614 _And<_IsNotSame<__remove_cvref_t<_Fp>, function>, __is_invocable_r<_Rp, _Fp&, _ArgTypes...>>::value>;
633615
634616public:
635617 typedef _Rp result_type;
......@@ -690,11 +672,11 @@ public:
690672
691673# if _LIBCPP_HAS_RTTI
692674 // function target access:
693 _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
675 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
694676 template <typename _Tp>
695 _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
677 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
696678 template <typename _Tp>
697 _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
679 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
698680# endif // _LIBCPP_HAS_RTTI
699681};
700682
lib/libcxx/include/__functional/hash.h+1-10
......@@ -433,13 +433,10 @@ struct __hash_impl<long double> : __scalar_hash<long double> {
433433template <class _Tp>
434434struct hash : public __hash_impl<_Tp> {};
435435
436#if _LIBCPP_STD_VER >= 17
437
438436template <>
439437struct hash<nullptr_t> : public __unary_function<nullptr_t, size_t> {
440 _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; }
438 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; }
441439};
442#endif
443440
444441#ifndef _LIBCPP_CXX03_LANG
445442template <class _Key, class _Hash>
......@@ -452,18 +449,12 @@ template <class _Key, class _Hash = hash<_Key> >
452449using __has_enabled_hash _LIBCPP_NODEBUG =
453450 integral_constant<bool, __check_hash_requirements<_Key, _Hash>::value && is_default_constructible<_Hash>::value >;
454451
455# if _LIBCPP_STD_VER >= 17
456452template <class _Type, class>
457453using __enable_hash_helper_imp _LIBCPP_NODEBUG = _Type;
458454
459455template <class _Type, class... _Keys>
460456using __enable_hash_helper _LIBCPP_NODEBUG =
461457 __enable_hash_helper_imp<_Type, __enable_if_t<__all<__has_enabled_hash<_Keys>::value...>::value> >;
462# else
463template <class _Type, class...>
464using __enable_hash_helper _LIBCPP_NODEBUG = _Type;
465# endif
466
467458#endif // !_LIBCPP_CXX03_LANG
468459
469460_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__functional/identity.h+1-1
......@@ -44,7 +44,7 @@ struct __is_identity<reference_wrapper<const __identity> > : true_type {};
4444
4545struct identity {
4646 template <class _Tp>
47 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_Tp&& __t) const noexcept {
47 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_LIBCPP_LIFETIMEBOUND _Tp&& __t) const noexcept {
4848 return std::forward<_Tp>(__t);
4949 }
5050
lib/libcxx/include/__functional/is_transparent.h+8
......@@ -29,6 +29,14 @@ inline const bool __is_transparent_v<_Tp, _Key, __void_t<typename _Tp::is_transp
2929
3030#endif
3131
32// Two types are considered transparently comparable if `comparator(key, arg)` is equivalent to `comparator(key,
33// <implicit cast to KeyT>(arg))`.
34//
35// This is different from `__is_transparent_v`, which is only a property of the comparator and doesn't provide
36// additional semantic guarantees.
37template <class _Comparator, class _KeyT, class _Arg, class = void>
38inline const bool __is_transparently_comparable_v = false;
39
3240_LIBCPP_END_NAMESPACE_STD
3341
3442#endif // _LIBCPP___FUNCTIONAL_IS_TRANSPARENT
lib/libcxx/include/__functional/mem_fn.h+2-1
......@@ -43,7 +43,8 @@ public:
4343};
4444
4545template <class _Rp, class _Tp>
46inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*> mem_fn(_Rp _Tp::*__pm) _NOEXCEPT {
46[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*>
47mem_fn(_Rp _Tp::* __pm) _NOEXCEPT {
4748 return __mem_fn<_Rp _Tp::*>(__pm);
4849}
4950
lib/libcxx/include/__functional/operations.h+18
......@@ -15,7 +15,9 @@
1515#include <__functional/unary_function.h>
1616#include <__fwd/functional.h>
1717#include <__type_traits/desugars_to.h>
18#include <__type_traits/is_generic_transparent_comparator.h>
1819#include <__type_traits/is_integral.h>
20#include <__type_traits/make_transparent.h>
1921#include <__utility/forward.h>
2022
2123#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -377,6 +379,14 @@ struct less<void> {
377379 typedef void is_transparent;
378380};
379381
382template <class _Tp>
383struct __make_transparent<_Tp, less<_Tp> > {
384 using type _LIBCPP_NODEBUG = less<>;
385};
386
387template <>
388inline const bool __is_generic_transparent_comparator_v<less<>> = true;
389
380390template <class _Tp, class _Up>
381391inline const bool __desugars_to_v<__less_tag, less<>, _Tp, _Up> = true;
382392
......@@ -466,6 +476,14 @@ struct greater<void> {
466476
467477template <class _Tp, class _Up>
468478inline const bool __desugars_to_v<__greater_tag, greater<>, _Tp, _Up> = true;
479
480template <class _Tp>
481struct __make_transparent<_Tp, greater<_Tp>> {
482 using type _LIBCPP_NODEBUG = greater<>;
483};
484
485template <>
486inline const bool __is_generic_transparent_comparator_v<greater<>> = true;
469487#endif
470488
471489// Logical operations
lib/libcxx/include/__functional/ranges_operations.h+7
......@@ -14,6 +14,7 @@
1414#include <__concepts/totally_ordered.h>
1515#include <__config>
1616#include <__type_traits/desugars_to.h>
17#include <__type_traits/is_generic_transparent_comparator.h>
1718#include <__utility/forward.h>
1819
1920#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -108,6 +109,12 @@ inline const bool __desugars_to_v<__less_tag, ranges::less, _Tp, _Up> = true;
108109template <class _Tp, class _Up>
109110inline const bool __desugars_to_v<__greater_tag, ranges::greater, _Tp, _Up> = true;
110111
112template <>
113inline const bool __is_generic_transparent_comparator_v<ranges::less> = true;
114
115template <>
116inline const bool __is_generic_transparent_comparator_v<ranges::greater> = true;
117
111118#endif // _LIBCPP_STD_VER >= 20
112119
113120_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__functional/reference_wrapper.h+7-5
......@@ -58,7 +58,7 @@ public:
5858
5959 // access
6060 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator type&() const _NOEXCEPT { return *__f_; }
61 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT { return *__f_; }
61 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT { return *__f_; }
6262
6363 // invoke
6464 template <class... _ArgTypes>
......@@ -128,23 +128,25 @@ reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
128128#endif
129129
130130template <class _Tp>
131inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT {
131[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
132_LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT {
132133 return reference_wrapper<_Tp>(__t);
133134}
134135
135136template <class _Tp>
136inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp>
137[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp>
137138ref(reference_wrapper<_Tp> __t) _NOEXCEPT {
138139 return __t;
139140}
140141
141142template <class _Tp>
142inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp> cref(const _Tp& __t) _NOEXCEPT {
143[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
144cref(const _Tp& __t) _NOEXCEPT {
143145 return reference_wrapper<const _Tp>(__t);
144146}
145147
146148template <class _Tp>
147inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
149[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp>
148150cref(reference_wrapper<_Tp> __t) _NOEXCEPT {
149151 return __t;
150152}
lib/libcxx/include/__functional/weak_result_type.h+14-28
......@@ -13,9 +13,9 @@
1313#include <__config>
1414#include <__functional/binary_function.h>
1515#include <__functional/unary_function.h>
16#include <__type_traits/integral_constant.h>
1716#include <__type_traits/invoke.h>
1817#include <__type_traits/is_same.h>
18#include <__type_traits/void_t.h>
1919#include <__utility/declval.h>
2020
2121#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -24,50 +24,36 @@
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
27template <class _Tp>
28struct __has_result_type {
29private:
30 template <class _Up>
31 static false_type __test(...);
32 template <class _Up>
33 static true_type __test(typename _Up::result_type* = 0);
27template <class _Tp, class = void>
28inline const bool __has_result_type_v = false;
3429
35public:
36 static const bool value = decltype(__test<_Tp>(0))::value;
37};
30template <class _Tp>
31inline const bool __has_result_type_v<_Tp, __void_t<typename _Tp::result_type*> > = true;
3832
3933// __weak_result_type
4034
4135template <class _Tp>
4236struct __derives_from_unary_function {
4337private:
44 struct __two {
45 char __lx;
46 char __lxx;
47 };
48 static __two __test(...);
38 static void __find_base(...);
4939 template <class _Ap, class _Rp>
50 static __unary_function<_Ap, _Rp> __test(const volatile __unary_function<_Ap, _Rp>*);
40 static __unary_function<_Ap, _Rp> __find_base(const volatile __unary_function<_Ap, _Rp>*);
5141
5242public:
53 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
54 typedef decltype(__test((_Tp*)0)) type;
43 using type = decltype(__find_base(static_cast<_Tp*>(nullptr)));
44 static const bool value = !is_same<type, void>::value;
5545};
5646
5747template <class _Tp>
5848struct __derives_from_binary_function {
5949private:
60 struct __two {
61 char __lx;
62 char __lxx;
63 };
64 static __two __test(...);
50 static void __find_base(...);
6551 template <class _A1, class _A2, class _Rp>
66 static __binary_function<_A1, _A2, _Rp> __test(const volatile __binary_function<_A1, _A2, _Rp>*);
52 static __binary_function<_A1, _A2, _Rp> __find_base(const volatile __binary_function<_A1, _A2, _Rp>*);
6753
6854public:
69 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
70 typedef decltype(__test((_Tp*)0)) type;
55 using type = decltype(__find_base(static_cast<_Tp*>(nullptr)));
56 static const bool value = !is_same<type, void>::value;
7157};
7258
7359template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
......@@ -85,7 +71,7 @@ struct __maybe_derive_from_binary_function // bool is true
8571template <class _Tp>
8672struct __maybe_derive_from_binary_function<_Tp, false> {};
8773
88template <class _Tp, bool = __has_result_type<_Tp>::value>
74template <class _Tp, bool = __has_result_type_v<_Tp> >
8975struct __weak_result_type_imp // bool is true
9076 : public __maybe_derive_from_unary_function<_Tp>,
9177 public __maybe_derive_from_binary_function<_Tp> {
lib/libcxx/include/__fwd/ios.h+1-1
......@@ -31,7 +31,7 @@ using wios = basic_ios<wchar_t>;
3131template <class _CharT, class _Traits>
3232class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios;
3333
34#if defined(_NEWLIB_VERSION)
34#if _LIBCPP_LIBC_NEWLIB
3535// On newlib, off_t is 'long int'
3636using streamoff = long int; // for char_traits in <string>
3737#else
lib/libcxx/include/__fwd/tuple.h+14
......@@ -21,11 +21,25 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2121template <size_t, class>
2222struct tuple_element;
2323
24template <size_t _Np, class _Tp>
25using __tuple_element_t _LIBCPP_NODEBUG = typename tuple_element<_Np, _Tp>::type;
26
2427#ifndef _LIBCPP_CXX03_LANG
2528
2629template <class...>
2730class tuple;
2831
32template <class>
33inline const bool __is_tuple_v = false;
34
35template <class... _Tp>
36inline const bool __is_tuple_v<tuple<_Tp...>> = true;
37
38template <size_t _Ip, class... _Tp>
39struct tuple_element<_Ip, tuple<_Tp...> > {
40 using type _LIBCPP_NODEBUG = __type_pack_element<_Ip, _Tp...>;
41};
42
2943template <class>
3044struct tuple_size;
3145
lib/libcxx/include/__hash_table+371-357
......@@ -10,6 +10,7 @@
1010#ifndef _LIBCPP___HASH_TABLE
1111#define _LIBCPP___HASH_TABLE
1212
13#include <__algorithm/fill_n.h>
1314#include <__algorithm/max.h>
1415#include <__algorithm/min.h>
1516#include <__assert>
......@@ -28,7 +29,6 @@
2829#include <__memory/swap_allocator.h>
2930#include <__memory/unique_ptr.h>
3031#include <__new/launder.h>
31#include <__type_traits/can_extract_key.h>
3232#include <__type_traits/copy_cvref.h>
3333#include <__type_traits/enable_if.h>
3434#include <__type_traits/invoke.h>
......@@ -44,7 +44,9 @@
4444#include <__utility/forward.h>
4545#include <__utility/move.h>
4646#include <__utility/pair.h>
47#include <__utility/scope_guard.h>
4748#include <__utility/swap.h>
49#include <__utility/try_key_extraction.h>
4850#include <limits>
4951
5052#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -81,18 +83,6 @@ struct __hash_node_base {
8183 typedef _NodePtr __node_pointer;
8284 typedef __node_base_pointer __next_pointer;
8385
84// TODO(LLVM 22): Remove this check
85#ifndef _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB
86 static_assert(sizeof(__node_base_pointer) == sizeof(__node_pointer) && _LIBCPP_ALIGNOF(__node_base_pointer) ==
87 _LIBCPP_ALIGNOF(__node_pointer),
88 "It looks like you are using std::__hash_table (an implementation detail for the unordered containers) "
89 "with a fancy pointer type that thas a different representation depending on whether it points to a "
90 "__hash_table base pointer or a __hash_table node pointer (both of which are implementation details of "
91 "the standard library). This means that your ABI is being broken between LLVM 19 and LLVM 20. If you "
92 "don't care about your ABI being broken, define the _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB macro to "
93 "silence this diagnostic.");
94#endif
95
9686 __next_pointer __next_;
9787
9888 _LIBCPP_HIDE_FROM_ABI __next_pointer __ptr() _NOEXCEPT {
......@@ -122,6 +112,19 @@ struct __get_hash_node_value_type<__hash_value_type<_Key, _Tp> > {
122112template <class _Tp>
123113using __get_hash_node_value_type_t _LIBCPP_NODEBUG = typename __get_hash_node_value_type<_Tp>::type;
124114
115template <class _Tp>
116struct __get_hash_node_key_type {
117 using type _LIBCPP_NODEBUG = _Tp;
118};
119
120template <class _Key, class _Tp>
121struct __get_hash_node_key_type<__hash_value_type<_Key, _Tp> > {
122 using type _LIBCPP_NODEBUG = _Key;
123};
124
125template <class _Tp>
126using __get_hash_node_key_type_t _LIBCPP_NODEBUG = typename __get_hash_node_key_type<_Tp>::type;
127
125128template <class _Tp, class _VoidPtr>
126129struct __hash_node : public __hash_node_base< __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > > {
127130 using __node_value_type _LIBCPP_NODEBUG = __get_hash_node_value_type_t<_Tp>;
......@@ -152,7 +155,12 @@ public:
152155 }
153156#endif
154157
155 _LIBCPP_HIDE_FROM_ABI explicit __hash_node(__next_pointer __next, size_t __hash) : _Base(__next), __hash_(__hash) {}
158 template <class _Alloc, class... _Args>
159 _LIBCPP_HIDE_FROM_ABI explicit __hash_node(size_t __hash, _Alloc& __na, _Args&&... __args)
160 : _Base(nullptr), __hash_(__hash) {
161 allocator_traits<_Alloc>::construct(__na, std::addressof(__get_value()), std::forward<_Args>(__args)...);
162 }
163
156164 _LIBCPP_HIDE_FROM_ABI ~__hash_node() {}
157165};
158166
......@@ -182,85 +190,16 @@ class __hash_map_iterator;
182190template <class _HashIterator>
183191class __hash_map_const_iterator;
184192
185template <class _Tp>
186struct __hash_key_value_types {
187 static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, "");
188 typedef _Tp key_type;
189 typedef _Tp __node_value_type;
190 typedef _Tp __container_value_type;
191 static const bool __is_map = false;
192
193 _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(_Tp const& __v) { return __v; }
194 _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(__node_value_type const& __v) { return __v; }
195 _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) { return std::addressof(__n); }
196 _LIBCPP_HIDE_FROM_ABI static __container_value_type&& __move(__node_value_type& __v) { return std::move(__v); }
197};
198
199template <class _Key, class _Tp>
200struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {
201 typedef _Key key_type;
202 typedef _Tp mapped_type;
203 typedef __hash_value_type<_Key, _Tp> __node_value_type;
204 typedef pair<const _Key, _Tp> __container_value_type;
205 typedef __container_value_type __map_value_type;
206 static const bool __is_map = true;
207
208 _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(__container_value_type const& __v) { return __v.first; }
209
210 template <class _Up, __enable_if_t<is_same<__remove_cvref_t<_Up>, __node_value_type>::value, int> = 0>
211 _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(_Up& __t) {
212 return __t.__get_value();
213 }
214
215 template <class _Up, __enable_if_t<is_same<__remove_cvref_t<_Up>, __container_value_type>::value, int> = 0>
216 _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(_Up& __t) {
217 return __t;
218 }
219
220 _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__container_value_type& __n) {
221 return std::addressof(__n);
222 }
223 _LIBCPP_HIDE_FROM_ABI static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { return __v.__move(); }
224};
225
226template <class _Tp, class _AllocPtr, class _KVTypes = __hash_key_value_types<_Tp>, bool = _KVTypes::__is_map>
227struct __hash_map_pointer_types {};
228
229template <class _Tp, class _AllocPtr, class _KVTypes>
230struct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
231 typedef typename _KVTypes::__map_value_type _Mv;
232 typedef __rebind_pointer_t<_AllocPtr, _Mv> __map_value_type_pointer;
233 typedef __rebind_pointer_t<_AllocPtr, const _Mv> __const_map_value_type_pointer;
234};
235
236193template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
237194struct __hash_node_types;
238195
239196template <class _NodePtr, class _Tp, class _VoidPtr>
240struct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> >
241 : public __hash_key_value_types<_Tp>,
242 __hash_map_pointer_types<_Tp, _VoidPtr>
243
244{
245 typedef __hash_key_value_types<_Tp> __base;
246
247public:
248 typedef ptrdiff_t difference_type;
249 typedef size_t size_type;
250
251 typedef __rebind_pointer_t<_NodePtr, void> __void_pointer;
252
197struct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> > {
253198 typedef typename pointer_traits<_NodePtr>::element_type __node_type;
254 typedef _NodePtr __node_pointer;
255199
256 typedef __hash_node_base<__node_pointer> __node_base_type;
257 typedef __rebind_pointer_t<_NodePtr, __node_base_type> __node_base_pointer;
258
259 typedef typename __node_base_type::__next_pointer __next_pointer;
200 typedef typename __hash_node_base<_NodePtr>::__next_pointer __next_pointer;
260201
261202 using __node_value_type _LIBCPP_NODEBUG = __get_hash_node_value_type_t<_Tp>;
262 typedef __rebind_pointer_t<_VoidPtr, __node_value_type> __node_value_type_pointer;
263 typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> __const_node_value_type_pointer;
264203
265204private:
266205 static_assert(!is_const<__node_type>::value, "_NodePtr should never be a pointer to const");
......@@ -281,13 +220,6 @@ struct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __has
281220template <class _NodePtr>
282221struct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
283222
284template <class _NodeValueTp, class _VoidPtr>
285struct __make_hash_node_types {
286 typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp;
287 typedef __rebind_pointer_t<_VoidPtr, _NodeTp> _NodePtr;
288 typedef __hash_node_types<_NodePtr> type;
289};
290
291223template <class _NodePtr>
292224class __hash_iterator {
293225 typedef __hash_node_types<_NodePtr> _NodeTypes;
......@@ -299,9 +231,9 @@ class __hash_iterator {
299231public:
300232 typedef forward_iterator_tag iterator_category;
301233 typedef typename _NodeTypes::__node_value_type value_type;
302 typedef typename _NodeTypes::difference_type difference_type;
234 using difference_type = ptrdiff_t;
303235 typedef value_type& reference;
304 typedef typename _NodeTypes::__node_value_type_pointer pointer;
236 using pointer = __rebind_pointer_t<_NodePtr, value_type>;
305237
306238 _LIBCPP_HIDE_FROM_ABI __hash_iterator() _NOEXCEPT : __node_(nullptr) {}
307239
......@@ -366,9 +298,9 @@ public:
366298
367299 typedef forward_iterator_tag iterator_category;
368300 typedef typename _NodeTypes::__node_value_type value_type;
369 typedef typename _NodeTypes::difference_type difference_type;
301 using difference_type = ptrdiff_t;
370302 typedef const value_type& reference;
371 typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
303 using pointer = __rebind_pointer_t<_NodePtr, const value_type>;
372304
373305 _LIBCPP_HIDE_FROM_ABI __hash_const_iterator() _NOEXCEPT : __node_(nullptr) {}
374306
......@@ -431,9 +363,9 @@ class __hash_local_iterator {
431363public:
432364 typedef forward_iterator_tag iterator_category;
433365 typedef typename _NodeTypes::__node_value_type value_type;
434 typedef typename _NodeTypes::difference_type difference_type;
366 using difference_type = ptrdiff_t;
435367 typedef value_type& reference;
436 typedef typename _NodeTypes::__node_value_type_pointer pointer;
368 using pointer = __rebind_pointer_t<_NodePtr, value_type>;
437369
438370 _LIBCPP_HIDE_FROM_ABI __hash_local_iterator() _NOEXCEPT : __node_(nullptr) {}
439371
......@@ -509,9 +441,9 @@ public:
509441
510442 typedef forward_iterator_tag iterator_category;
511443 typedef typename _NodeTypes::__node_value_type value_type;
512 typedef typename _NodeTypes::difference_type difference_type;
444 using difference_type = ptrdiff_t;
513445 typedef const value_type& reference;
514 typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
446 using pointer = __rebind_pointer_t<_ConstNodePtr, const value_type>;
515447
516448 _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) {}
517449
......@@ -617,8 +549,6 @@ public:
617549 typedef typename __alloc_traits::pointer pointer;
618550
619551private:
620 typedef __hash_node_types<pointer> _NodeTypes;
621
622552 allocator_type& __na_;
623553
624554public:
......@@ -633,7 +563,7 @@ public:
633563
634564 _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
635565 if (__value_constructed) {
636 __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__get_value()));
566 __alloc_traits::destroy(__na_, std::addressof(__p->__get_value()));
637567 std::__destroy_at(std::addressof(*__p));
638568 }
639569 if (__p)
......@@ -684,18 +614,16 @@ template <class _Tp, class _Hash, class _Equal, class _Alloc>
684614class __hash_table {
685615public:
686616 using value_type = __get_hash_node_value_type_t<_Tp>;
617 using key_type = __get_hash_node_key_type_t<_Tp>;
618
687619 typedef _Hash hasher;
688620 typedef _Equal key_equal;
689621 typedef _Alloc allocator_type;
690622
691623private:
692624 typedef allocator_traits<allocator_type> __alloc_traits;
693 typedef typename __make_hash_node_types<_Tp, typename __alloc_traits::void_pointer>::type _NodeTypes;
694625
695626public:
696 typedef typename _NodeTypes::__node_value_type __node_value_type;
697 typedef typename _NodeTypes::__container_value_type __container_value_type;
698 typedef typename _NodeTypes::key_type key_type;
699627 typedef value_type& reference;
700628 typedef const value_type& const_reference;
701629 typedef typename __alloc_traits::pointer pointer;
......@@ -703,22 +631,23 @@ public:
703631#ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
704632 typedef typename __alloc_traits::size_type size_type;
705633#else
706 typedef typename _NodeTypes::size_type size_type;
634 using size_type = size_t;
707635#endif
708 typedef typename _NodeTypes::difference_type difference_type;
636 using difference_type = ptrdiff_t;
709637
710638public:
711639 // Create __node
712640
713 typedef typename _NodeTypes::__node_type __node;
714 typedef __rebind_alloc<__alloc_traits, __node> __node_allocator;
715 typedef allocator_traits<__node_allocator> __node_traits;
716 typedef typename _NodeTypes::__void_pointer __void_pointer;
717 typedef typename _NodeTypes::__node_pointer __node_pointer;
718 typedef typename _NodeTypes::__node_pointer __node_const_pointer;
719 typedef typename _NodeTypes::__node_base_type __first_node;
720 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
721 typedef typename _NodeTypes::__next_pointer __next_pointer;
641 using __void_pointer _LIBCPP_NODEBUG = typename __alloc_traits::void_pointer;
642
643 using __node _LIBCPP_NODEBUG = __hash_node<_Tp, __void_pointer>;
644 using __node_allocator _LIBCPP_NODEBUG = __rebind_alloc<__alloc_traits, __node>;
645 using __node_traits _LIBCPP_NODEBUG = allocator_traits<__node_allocator>;
646 using __node_pointer _LIBCPP_NODEBUG = __rebind_pointer_t<__void_pointer, __node>;
647
648 using __first_node _LIBCPP_NODEBUG = __hash_node_base<__node_pointer>;
649 using __node_base_pointer _LIBCPP_NODEBUG = __rebind_pointer_t<__void_pointer, __first_node>;
650 using __next_pointer _LIBCPP_NODEBUG = __node_base_pointer;
722651
723652private:
724653 // check for sane allocator pointer rebinding semantics. Rebinding the
......@@ -747,6 +676,38 @@ private:
747676
748677 _LIBCPP_HIDE_FROM_ABI size_type& size() _NOEXCEPT { return __size_; }
749678
679 _LIBCPP_HIDE_FROM_ABI void
680 __copy_construct(__next_pointer __other_iter, __next_pointer __own_iter, size_t __current_chash) {
681 auto __bucket_count = bucket_count();
682
683 for (; __other_iter; __other_iter = __other_iter->__next_) {
684 __node_holder __new_node = __construct_node_hash(__other_iter->__hash(), __other_iter->__upcast()->__get_value());
685
686 size_t __new_chash = std::__constrain_hash(__new_node->__hash(), __bucket_count);
687 if (__new_chash != __current_chash) {
688 __bucket_list_[__new_chash] = __own_iter;
689 __current_chash = __new_chash;
690 }
691
692 __own_iter->__next_ = static_cast<__next_pointer>(__new_node.release());
693 __own_iter = __own_iter->__next_;
694 }
695 }
696
697 _LIBCPP_HIDE_FROM_ABI void __copy_construct(__next_pointer __other_iter) {
698 __next_pointer __own_iter = __first_node_.__ptr();
699 {
700 __node_holder __new_node = __construct_node_hash(__other_iter->__hash(), __other_iter->__upcast()->__get_value());
701 __own_iter->__next_ = static_cast<__next_pointer>(__new_node.release());
702 }
703
704 size_t __current_chash = std::__constrain_hash(__own_iter->__next_->__hash(), bucket_count());
705 __bucket_list_[__current_chash] = __own_iter;
706 __other_iter = __other_iter->__next_;
707 __own_iter = __own_iter->__next_;
708 __copy_construct(__other_iter, __own_iter, __current_chash);
709 }
710
750711public:
751712 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }
752713
......@@ -811,40 +772,66 @@ public:
811772 _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(__node_pointer __nd);
812773 _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
813774
814 template <class _Key, class... _Args>
815 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args);
816
817 template <class... _Args>
818 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
819
820 template <class _Pp>
821 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_Pp&& __x) {
822 return __emplace_unique_extract_key(std::forward<_Pp>(__x), __can_extract_key<_Pp, key_type>());
823 }
824
825 template <class _First,
826 class _Second,
827 __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, int> = 0>
828 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_First&& __f, _Second&& __s) {
829 return __emplace_unique_key_args(__f, std::forward<_First>(__f), std::forward<_Second>(__s));
830 }
831
832775 template <class... _Args>
833776 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_Args&&... __args) {
834 return __emplace_unique_impl(std::forward<_Args>(__args)...);
835 }
836
837 template <class _Pp>
838 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
839 return __emplace_unique_impl(std::forward<_Pp>(__x));
840 }
841 template <class _Pp>
842 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
843 return __emplace_unique_key_args(__x, std::forward<_Pp>(__x));
844 }
845 template <class _Pp>
846 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
847 return __emplace_unique_key_args(__x.first, std::forward<_Pp>(__x));
777 return std::__try_key_extraction<key_type>(
778 [this](const key_type& __key, _Args&&... __args2) {
779 size_t __hash = hash_function()(__key);
780 size_type __bc = bucket_count();
781 bool __inserted = false;
782 __next_pointer __nd;
783 size_t __chash;
784 if (__bc != 0) {
785 __chash = std::__constrain_hash(__hash, __bc);
786 __nd = __bucket_list_[__chash];
787 if (__nd != nullptr) {
788 for (__nd = __nd->__next_;
789 __nd != nullptr &&
790 (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
791 __nd = __nd->__next_) {
792 if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__get_value(), __key))
793 goto __done;
794 }
795 }
796 }
797 {
798 __node_holder __h = __construct_node_hash(__hash, std::forward<_Args>(__args2)...);
799 if (size() + 1 > __bc * max_load_factor()) {
800 __rehash_unique(std::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc),
801 size_type(__math::ceil(float(size() + 1) / max_load_factor()))));
802 __bc = bucket_count();
803 __chash = std::__constrain_hash(__hash, __bc);
804 }
805 // insert_after __bucket_list_[__chash], or __first_node if bucket is null
806 __next_pointer __pn = __bucket_list_[__chash];
807 if (__pn == nullptr) {
808 __pn = __first_node_.__ptr();
809 __h->__next_ = __pn->__next_;
810 __pn->__next_ = __h.get()->__ptr();
811 // fix up __bucket_list_
812 __bucket_list_[__chash] = __pn;
813 if (__h->__next_ != nullptr)
814 __bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)] = __h.get()->__ptr();
815 } else {
816 __h->__next_ = __pn->__next_;
817 __pn->__next_ = static_cast<__next_pointer>(__h.get());
818 }
819 __nd = static_cast<__next_pointer>(__h.release());
820 // increment size
821 ++size();
822 __inserted = true;
823 }
824 __done:
825 return pair<iterator, bool>(iterator(__nd), __inserted);
826 },
827 [this](_Args&&... __args2) {
828 __node_holder __h = __construct_node(std::forward<_Args>(__args2)...);
829 pair<iterator, bool> __r = __node_insert_unique(__h.get());
830 if (__r.second)
831 __h.release();
832 return __r;
833 },
834 std::forward<_Args>(__args)...);
848835 }
849836
850837 template <class... _Args>
......@@ -854,9 +841,7 @@ public:
854841
855842 template <class _ValueT = _Tp, __enable_if_t<__is_hash_value_type<_ValueT>::value, int> = 0>
856843 _LIBCPP_HIDE_FROM_ABI void __insert_unique_from_orphaned_node(value_type&& __value) {
857 using __key_type = typename _NodeTypes::key_type;
858
859 __node_holder __h = __construct_node(const_cast<__key_type&&>(__value.first), std::move(__value.second));
844 __node_holder __h = __construct_node(const_cast<key_type&&>(__value.first), std::move(__value.second));
860845 __node_insert_unique(__h.get());
861846 __h.release();
862847 }
......@@ -870,9 +855,7 @@ public:
870855
871856 template <class _ValueT = _Tp, __enable_if_t<__is_hash_value_type<_ValueT>::value, int> = 0>
872857 _LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(value_type&& __value) {
873 using __key_type = typename _NodeTypes::key_type;
874
875 __node_holder __h = __construct_node(const_cast<__key_type&&>(__value.first), std::move(__value.second));
858 __node_holder __h = __construct_node(const_cast<key_type&&>(__value.first), std::move(__value.second));
876859 __node_insert_multi(__h.get());
877860 __h.release();
878861 }
......@@ -1017,8 +1000,8 @@ private:
10171000 template <class... _Args>
10181001 _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&&... __args);
10191002
1020 template <class _First, class... _Rest>
1021 _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest);
1003 template <class... _Args>
1004 _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_hash(size_t __hash, _Args&&... __args);
10221005
10231006 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table& __u) {
10241007 __copy_assign_alloc(__u, integral_constant<bool, __node_traits::propagate_on_container_copy_assignment::value>());
......@@ -1042,17 +1025,29 @@ private:
10421025 }
10431026 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
10441027
1045 _LIBCPP_HIDE_FROM_ABI void __deallocate_node(__next_pointer __np) _NOEXCEPT;
1028 _LIBCPP_HIDE_FROM_ABI void __deallocate_node(__node_pointer __nd) _NOEXCEPT {
1029 auto& __alloc = __node_alloc();
1030 __node_traits::destroy(__alloc, std::addressof(__nd->__get_value()));
1031 std::__destroy_at(std::__to_address(__nd));
1032 __node_traits::deallocate(__alloc, __nd, 1);
1033 }
1034
1035 _LIBCPP_HIDE_FROM_ABI void __deallocate_node_list(__next_pointer __np) _NOEXCEPT {
1036 while (__np != nullptr) {
1037 __next_pointer __next = __np->__next_;
1038 __deallocate_node(__np->__upcast());
1039 __np = __next;
1040 }
1041 }
1042
10461043 _LIBCPP_HIDE_FROM_ABI __next_pointer __detach() _NOEXCEPT;
10471044
10481045 template <class _From, class _ValueT = _Tp, __enable_if_t<__is_hash_value_type<_ValueT>::value, int> = 0>
10491046 _LIBCPP_HIDE_FROM_ABI void __assign_value(__get_hash_node_value_type_t<_Tp>& __lhs, _From&& __rhs) {
1050 using __key_type = typename _NodeTypes::key_type;
1051
10521047 // This is technically UB, since the object was constructed as `const`.
10531048 // Clang doesn't optimize on this currently though.
1054 const_cast<__key_type&>(__lhs.first) = const_cast<__copy_cvref_t<_From, __key_type>&&>(__rhs.first);
1055 __lhs.second = std::forward<_From>(__rhs).second;
1049 const_cast<key_type&>(__lhs.first) = const_cast<__copy_cvref_t<_From, key_type>&&>(__rhs.first);
1050 __lhs.second = std::forward<_From>(__rhs).second;
10561051 }
10571052
10581053 template <class _From, class _ValueT = _Tp, __enable_if_t<!__is_hash_value_type<_ValueT>::value, int> = 0>
......@@ -1101,16 +1096,29 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a
11011096 __max_load_factor_(1.0f) {}
11021097
11031098template <class _Tp, class _Hash, class _Equal, class _Alloc>
1104__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u)
1099__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __other)
11051100 : __bucket_list_(nullptr,
1106 __bucket_list_deleter(allocator_traits<__pointer_allocator>::select_on_container_copy_construction(
1107 __u.__bucket_list_.get_deleter().__alloc()),
1101 __bucket_list_deleter(__pointer_alloc_traits::select_on_container_copy_construction(
1102 __other.__bucket_list_.get_deleter().__alloc()),
11081103 0)),
1109 __node_alloc_(allocator_traits<__node_allocator>::select_on_container_copy_construction(__u.__node_alloc())),
1104 __node_alloc_(__node_traits::select_on_container_copy_construction(__other.__node_alloc())),
11101105 __size_(0),
1111 __hasher_(__u.hash_function()),
1112 __max_load_factor_(__u.__max_load_factor_),
1113 __key_eq_(__u.__key_eq_) {}
1106 __hasher_(__other.hash_function()),
1107 __max_load_factor_(__other.__max_load_factor_),
1108 __key_eq_(__other.__key_eq_) {
1109 if (__other.size() == 0)
1110 return;
1111
1112 auto& __bucket_list_del = __bucket_list_.get_deleter();
1113 auto __bucket_count = __other.bucket_count();
1114 __bucket_list_.reset(__pointer_alloc_traits::allocate(__bucket_list_del.__alloc(), __bucket_count));
1115 __bucket_list_del.size() = __bucket_count;
1116
1117 std::fill_n(__bucket_list_.get(), __bucket_count, nullptr);
1118
1119 __copy_construct(__other.__first_node_.__next_);
1120 __size_ = __other.size();
1121}
11141122
11151123template <class _Tp, class _Hash, class _Equal, class _Alloc>
11161124__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, const allocator_type& __a)
......@@ -1169,7 +1177,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() {
11691177 static_assert(is_copy_constructible<hasher>::value, "Hasher must be copy-constructible.");
11701178#endif
11711179
1172 __deallocate_node(__first_node_.__next_);
1180 __deallocate_node_list(__first_node_.__next_);
11731181}
11741182
11751183template <class _Tp, class _Hash, class _Equal, class _Alloc>
......@@ -1184,28 +1192,76 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc(const __hash_
11841192}
11851193
11861194template <class _Tp, class _Hash, class _Equal, class _Alloc>
1187__hash_table<_Tp, _Hash, _Equal, _Alloc>& __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) {
1188 if (this != std::addressof(__u)) {
1189 __copy_assign_alloc(__u);
1190 hash_function() = __u.hash_function();
1191 key_eq() = __u.key_eq();
1192 max_load_factor() = __u.max_load_factor();
1193 __assign_multi(__u.begin(), __u.end());
1195__hash_table<_Tp, _Hash, _Equal, _Alloc>&
1196__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __other) {
1197 if (this == std::addressof(__other))
1198 return *this;
1199
1200 __copy_assign_alloc(__other);
1201 hash_function() = __other.hash_function();
1202 key_eq() = __other.key_eq();
1203 max_load_factor() = __other.max_load_factor();
1204
1205 if (__other.size() == 0) {
1206 clear();
1207 return *this;
11941208 }
1195 return *this;
1196}
11971209
1198template <class _Tp, class _Hash, class _Equal, class _Alloc>
1199void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) _NOEXCEPT {
1200 __node_allocator& __na = __node_alloc();
1201 while (__np != nullptr) {
1202 __next_pointer __next = __np->__next_;
1203 __node_pointer __real_np = __np->__upcast();
1204 __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__get_value()));
1205 std::__destroy_at(std::addressof(*__real_np));
1206 __node_traits::deallocate(__na, __real_np, 1);
1207 __np = __next;
1210 auto __bucket_count = __other.bucket_count();
1211 if (__bucket_count != bucket_count()) {
1212 auto& __bucket_list_del = __bucket_list_.get_deleter();
1213 __bucket_list_.reset(__pointer_alloc_traits::allocate(__bucket_list_del.__alloc(), __bucket_count));
1214 __bucket_list_del.size() = __bucket_count;
1215 }
1216 std::fill_n(__bucket_list_.get(), __bucket_count, nullptr);
1217
1218 if (!__first_node_.__next_) {
1219 __copy_construct(__other.__first_node_.__next_);
1220 __size_ = __other.size();
1221 return *this;
1222 }
1223
1224 __next_pointer __other_iter = __other.__first_node_.__next_;
1225 __next_pointer __own_iter = __first_node_.__ptr();
1226 {
1227 __node_pointer __next = __own_iter->__next_->__upcast();
1228 __assign_value(__next->__get_value(), __other_iter->__upcast()->__get_value());
1229 __next->__hash_ = __other_iter->__hash();
1230 }
1231 size_t __current_chash = std::__constrain_hash(__own_iter->__next_->__hash(), __bucket_count);
1232 __bucket_list_[__current_chash] = __own_iter;
1233 __other_iter = __other_iter->__next_;
1234 __own_iter = __own_iter->__next_;
1235
1236 // Go through the nodes of the incoming hash table and copy then into the destination hash table, reusing as many
1237 // existing nodes as posssible in the destination.
1238 while (__other_iter && __own_iter->__next_) {
1239 __node_pointer __next = __own_iter->__next_->__upcast();
1240 __assign_value(__next->__get_value(), __other_iter->__upcast()->__get_value());
1241 __next->__hash_ = __other_iter->__hash();
1242
1243 size_t __new_chash = std::__constrain_hash(__next->__hash_, __bucket_count);
1244 if (__new_chash != __current_chash) {
1245 __bucket_list_[__new_chash] = __own_iter;
1246 __current_chash = __new_chash;
1247 }
1248
1249 __other_iter = __other_iter->__next_;
1250 __own_iter = __own_iter->__next_;
12081251 }
1252
1253 // At this point we either have consumed the whole incoming hash table, or we don't have any more nodes to reuse in
1254 // the destination. Either continue with constructing new nodes, or deallocate the left over nodes.
1255 if (__own_iter->__next_) {
1256 __deallocate_node_list(__own_iter->__next_);
1257 __own_iter->__next_ = nullptr;
1258 } else {
1259 __copy_construct(__other_iter, __own_iter, __current_chash);
1260 }
1261
1262 __size_ = __other.size();
1263
1264 return *this;
12091265}
12101266
12111267template <class _Tp, class _Hash, class _Equal, class _Alloc>
......@@ -1251,23 +1307,14 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(__hash_table& __u,
12511307 max_load_factor() = __u.max_load_factor();
12521308 if (bucket_count() != 0) {
12531309 __next_pointer __cache = __detach();
1254#if _LIBCPP_HAS_EXCEPTIONS
1255 try {
1256#endif // _LIBCPP_HAS_EXCEPTIONS
1257 const_iterator __i = __u.begin();
1258 while (__cache != nullptr && __u.size() != 0) {
1259 __assign_value(__cache->__upcast()->__get_value(), std::move(__u.remove(__i++)->__get_value()));
1260 __next_pointer __next = __cache->__next_;
1261 __node_insert_multi(__cache->__upcast());
1262 __cache = __next;
1263 }
1264#if _LIBCPP_HAS_EXCEPTIONS
1265 } catch (...) {
1266 __deallocate_node(__cache);
1267 throw;
1310 auto __guard = std::__make_scope_guard([&] { __deallocate_node_list(__cache); });
1311 const_iterator __i = __u.begin();
1312 while (__cache != nullptr && __u.size() != 0) {
1313 __assign_value(__cache->__upcast()->__get_value(), std::move(__u.remove(__i++)->__get_value()));
1314 __next_pointer __next = __cache->__next_;
1315 __node_insert_multi(__cache->__upcast());
1316 __cache = __next;
12681317 }
1269#endif // _LIBCPP_HAS_EXCEPTIONS
1270 __deallocate_node(__cache);
12711318 }
12721319 const_iterator __i = __u.begin();
12731320 while (__u.size() != 0)
......@@ -1290,27 +1337,18 @@ template <class _InputIterator>
12901337void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, _InputIterator __last) {
12911338 typedef iterator_traits<_InputIterator> _ITraits;
12921339 typedef typename _ITraits::value_type _ItValueType;
1293 static_assert(is_same<_ItValueType, __container_value_type>::value,
1294 "__assign_unique may only be called with the containers value type");
1340 static_assert(
1341 is_same<_ItValueType, value_type>::value, "__assign_unique may only be called with the containers value type");
12951342
12961343 if (bucket_count() != 0) {
12971344 __next_pointer __cache = __detach();
1298#if _LIBCPP_HAS_EXCEPTIONS
1299 try {
1300#endif // _LIBCPP_HAS_EXCEPTIONS
1301 for (; __cache != nullptr && __first != __last; ++__first) {
1302 __assign_value(__cache->__upcast()->__get_value(), *__first);
1303 __next_pointer __next = __cache->__next_;
1304 __node_insert_unique(__cache->__upcast());
1305 __cache = __next;
1306 }
1307#if _LIBCPP_HAS_EXCEPTIONS
1308 } catch (...) {
1309 __deallocate_node(__cache);
1310 throw;
1345 auto __guard = std::__make_scope_guard([&] { __deallocate_node_list(__cache); });
1346 for (; __cache != nullptr && __first != __last; ++__first) {
1347 __assign_value(__cache->__upcast()->__get_value(), *__first);
1348 __next_pointer __next = __cache->__next_;
1349 __node_insert_unique(__cache->__upcast());
1350 __cache = __next;
13111351 }
1312#endif // _LIBCPP_HAS_EXCEPTIONS
1313 __deallocate_node(__cache);
13141352 }
13151353 for (; __first != __last; ++__first)
13161354 __emplace_unique(*__first);
......@@ -1321,31 +1359,20 @@ template <class _InputIterator>
13211359void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, _InputIterator __last) {
13221360 typedef iterator_traits<_InputIterator> _ITraits;
13231361 typedef typename _ITraits::value_type _ItValueType;
1324 static_assert(
1325 (is_same<_ItValueType, __container_value_type>::value || is_same<_ItValueType, __node_value_type>::value),
1326 "__assign_multi may only be called with the containers value type"
1327 " or the nodes value type");
1362 static_assert(is_same<_ItValueType, value_type>::value,
1363 "__assign_multi may only be called with the containers value type or the nodes value type");
13281364 if (bucket_count() != 0) {
13291365 __next_pointer __cache = __detach();
1330#if _LIBCPP_HAS_EXCEPTIONS
1331 try {
1332#endif // _LIBCPP_HAS_EXCEPTIONS
1333 for (; __cache != nullptr && __first != __last; ++__first) {
1334 __assign_value(__cache->__upcast()->__get_value(), *__first);
1335 __next_pointer __next = __cache->__next_;
1336 __node_insert_multi(__cache->__upcast());
1337 __cache = __next;
1338 }
1339#if _LIBCPP_HAS_EXCEPTIONS
1340 } catch (...) {
1341 __deallocate_node(__cache);
1342 throw;
1366 auto __guard = std::__make_scope_guard([&] { __deallocate_node_list(__cache); });
1367 for (; __cache != nullptr && __first != __last; ++__first) {
1368 __assign_value(__cache->__upcast()->__get_value(), *__first);
1369 __next_pointer __next = __cache->__next_;
1370 __node_insert_multi(__cache->__upcast());
1371 __cache = __next;
13431372 }
1344#endif // _LIBCPP_HAS_EXCEPTIONS
1345 __deallocate_node(__cache);
13461373 }
13471374 for (; __first != __last; ++__first)
1348 __emplace_multi(_NodeTypes::__get_value(*__first));
1375 __emplace_multi(*__first);
13491376}
13501377
13511378template <class _Tp, class _Hash, class _Equal, class _Alloc>
......@@ -1375,7 +1402,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT {
13751402template <class _Tp, class _Hash, class _Equal, class _Alloc>
13761403void __hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT {
13771404 if (size() > 0) {
1378 __deallocate_node(__first_node_.__next_);
1405 __deallocate_node_list(__first_node_.__next_);
13791406 __first_node_.__next_ = nullptr;
13801407 size_type __bc = bucket_count();
13811408 for (size_type __i = 0; __i < __bc; ++__i)
......@@ -1561,69 +1588,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(const_iterator __p
15611588 return __node_insert_multi(__cp);
15621589}
15631590
1564template <class _Tp, class _Hash, class _Equal, class _Alloc>
1565template <class _Key, class... _Args>
1566pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
1567__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) {
1568 size_t __hash = hash_function()(__k);
1569 size_type __bc = bucket_count();
1570 bool __inserted = false;
1571 __next_pointer __nd;
1572 size_t __chash;
1573 if (__bc != 0) {
1574 __chash = std::__constrain_hash(__hash, __bc);
1575 __nd = __bucket_list_[__chash];
1576 if (__nd != nullptr) {
1577 for (__nd = __nd->__next_;
1578 __nd != nullptr && (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
1579 __nd = __nd->__next_) {
1580 if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__get_value(), __k))
1581 goto __done;
1582 }
1583 }
1584 }
1585 {
1586 __node_holder __h = __construct_node_hash(__hash, std::forward<_Args>(__args)...);
1587 if (size() + 1 > __bc * max_load_factor() || __bc == 0) {
1588 __rehash_unique(std::max<size_type>(
1589 2 * __bc + !std::__is_hash_power2(__bc), size_type(__math::ceil(float(size() + 1) / max_load_factor()))));
1590 __bc = bucket_count();
1591 __chash = std::__constrain_hash(__hash, __bc);
1592 }
1593 // insert_after __bucket_list_[__chash], or __first_node if bucket is null
1594 __next_pointer __pn = __bucket_list_[__chash];
1595 if (__pn == nullptr) {
1596 __pn = __first_node_.__ptr();
1597 __h->__next_ = __pn->__next_;
1598 __pn->__next_ = __h.get()->__ptr();
1599 // fix up __bucket_list_
1600 __bucket_list_[__chash] = __pn;
1601 if (__h->__next_ != nullptr)
1602 __bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)] = __h.get()->__ptr();
1603 } else {
1604 __h->__next_ = __pn->__next_;
1605 __pn->__next_ = static_cast<__next_pointer>(__h.get());
1606 }
1607 __nd = static_cast<__next_pointer>(__h.release());
1608 // increment size
1609 ++size();
1610 __inserted = true;
1611 }
1612__done:
1613 return pair<iterator, bool>(iterator(__nd), __inserted);
1614}
1615
1616template <class _Tp, class _Hash, class _Equal, class _Alloc>
1617template <class... _Args>
1618pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
1619__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args) {
1620 __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
1621 pair<iterator, bool> __r = __node_insert_unique(__h.get());
1622 if (__r.second)
1623 __h.release();
1624 return __r;
1625}
1626
16271591template <class _Tp, class _Hash, class _Equal, class _Alloc>
16281592template <class... _Args>
16291593typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
......@@ -1764,41 +1728,45 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n) _LIBCPP_D
17641728
17651729template <class _Tp, class _Hash, class _Equal, class _Alloc>
17661730template <bool _UniqueKeys>
1767void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc) {
1768 __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
1769 __bucket_list_.reset(__nbc > 0 ? __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
1770 __bucket_list_.get_deleter().size() = __nbc;
1771 if (__nbc > 0) {
1772 for (size_type __i = 0; __i < __nbc; ++__i)
1773 __bucket_list_[__i] = nullptr;
1774 __next_pointer __pp = __first_node_.__ptr();
1775 __next_pointer __cp = __pp->__next_;
1776 if (__cp != nullptr) {
1777 size_type __chash = std::__constrain_hash(__cp->__hash(), __nbc);
1778 __bucket_list_[__chash] = __pp;
1779 size_type __phash = __chash;
1780 for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; __cp = __pp->__next_) {
1781 __chash = std::__constrain_hash(__cp->__hash(), __nbc);
1782 if (__chash == __phash)
1783 __pp = __cp;
1784 else {
1785 if (__bucket_list_[__chash] == nullptr) {
1786 __bucket_list_[__chash] = __pp;
1787 __pp = __cp;
1788 __phash = __chash;
1789 } else {
1790 __next_pointer __np = __cp;
1791 if _LIBCPP_CONSTEXPR_SINCE_CXX17 (!_UniqueKeys) {
1792 for (; __np->__next_ != nullptr &&
1793 key_eq()(__cp->__upcast()->__get_value(), __np->__next_->__upcast()->__get_value());
1794 __np = __np->__next_)
1795 ;
1796 }
1797 __pp->__next_ = __np->__next_;
1798 __np->__next_ = __bucket_list_[__chash]->__next_;
1799 __bucket_list_[__chash]->__next_ = __cp;
1800 }
1731void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __bucket_count) {
1732 __pointer_allocator& __ptr_alloc = __bucket_list_.get_deleter().__alloc();
1733 __bucket_list_.reset(__bucket_count > 0 ? __pointer_alloc_traits::allocate(__ptr_alloc, __bucket_count) : nullptr);
1734 __bucket_list_.get_deleter().size() = __bucket_count;
1735
1736 if (__bucket_count == 0)
1737 return;
1738
1739 for (size_type __i = 0; __i < __bucket_count; ++__i)
1740 __bucket_list_[__i] = nullptr;
1741 __next_pointer __pp = __first_node_.__ptr();
1742 __next_pointer __cp = __pp->__next_;
1743
1744 if (!__cp)
1745 return;
1746
1747 size_type __chash = std::__constrain_hash(__cp->__hash(), __bucket_count);
1748 __bucket_list_[__chash] = __pp;
1749 size_type __phash = __chash;
1750 for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; __cp = __pp->__next_) {
1751 __chash = std::__constrain_hash(__cp->__hash(), __bucket_count);
1752 if (__chash == __phash)
1753 __pp = __cp;
1754 else {
1755 if (__bucket_list_[__chash] == nullptr) {
1756 __bucket_list_[__chash] = __pp;
1757 __pp = __cp;
1758 __phash = __chash;
1759 } else {
1760 __next_pointer __np = __cp;
1761 if _LIBCPP_CONSTEXPR (!_UniqueKeys) {
1762 for (; __np->__next_ != nullptr &&
1763 key_eq()(__cp->__upcast()->__get_value(), __np->__next_->__upcast()->__get_value());
1764 __np = __np->__next_)
1765 ;
18011766 }
1767 __pp->__next_ = __np->__next_;
1768 __np->__next_ = __bucket_list_[__chash]->__next_;
1769 __bucket_list_[__chash]->__next_ = __cp;
18021770 }
18031771 }
18041772 }
......@@ -1854,16 +1822,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&&... __args) {
18541822 __node_allocator& __na = __node_alloc();
18551823 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
18561824
1857 // Begin the lifetime of the node itself. Note that this doesn't begin the lifetime of the value
1858 // held inside the node, since we need to use the allocator's construct() method for that.
1825 // Begin the lifetime of the node itself and the value_type contained within.
18591826 //
18601827 // We don't use the allocator's construct() method to construct the node itself since the
18611828 // Cpp17FooInsertable named requirements don't require the allocator's construct() method
18621829 // to work on anything other than the value_type.
1863 std::__construct_at(std::addressof(*__h), /* next = */ nullptr, /* hash = */ 0);
1830 std::__construct_at(std::addressof(*__h), /* hash = */ 0, __na, std::forward<_Args>(__args)...);
18641831
1865 // Now construct the value_type using the allocator's construct() method.
1866 __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__get_value()), std::forward<_Args>(__args)...);
18671832 __h.get_deleter().__value_constructed = true;
18681833
18691834 __h->__hash_ = hash_function()(__h->__get_value());
......@@ -1871,15 +1836,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&&... __args) {
18711836}
18721837
18731838template <class _Tp, class _Hash, class _Equal, class _Alloc>
1874template <class _First, class... _Rest>
1839template <class... _Args>
18751840typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
1876__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest) {
1877 static_assert(!__is_hash_value_type<_First, _Rest...>::value, "Construct cannot be called with a hash value type");
1841__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(size_t __hash, _Args&&... __args) {
1842 static_assert(!__is_hash_value_type<_Args...>::value, "Construct cannot be called with a hash value type");
18781843 __node_allocator& __na = __node_alloc();
18791844 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1880 std::__construct_at(std::addressof(*__h), /* next = */ nullptr, /* hash = */ __hash);
1881 __node_traits::construct(
1882 __na, _NodeTypes::__get_ptr(__h->__get_value()), std::forward<_First>(__f), std::forward<_Rest>(__rest)...);
1845 std::__construct_at(std::addressof(*__h), /* hash = */ __hash, __na, std::forward<_Args>(__args)...);
18831846 __h.get_deleter().__value_constructed = true;
18841847 return __h;
18851848}
......@@ -1899,12 +1862,63 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) {
18991862template <class _Tp, class _Hash, class _Equal, class _Alloc>
19001863typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
19011864__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, const_iterator __last) {
1902 for (const_iterator __p = __first; __first != __last; __p = __first) {
1903 ++__first;
1904 erase(__p);
1865 if (__first == __last)
1866 return iterator(__last.__node_);
1867
1868 // current node
1869 __next_pointer __current = __first.__node_;
1870 size_type __bucket_count = bucket_count();
1871 size_t __chash = std::__constrain_hash(__current->__hash(), __bucket_count);
1872 // find previous node
1873 __next_pointer __before_first = __bucket_list_[__chash];
1874 for (; __before_first->__next_ != __current; __before_first = __before_first->__next_)
1875 ;
1876
1877 __next_pointer __last_node = __last.__node_;
1878
1879 // If __before_first is in the same bucket (i.e. the first element we erase is not the first in the bucket), clear
1880 // this bucket first without re-linking it
1881 if (__before_first != __first_node_.__ptr() &&
1882 std::__constrain_hash(__before_first->__hash(), __bucket_count) == __chash) {
1883 while (__current != __last_node) {
1884 auto __next = __current->__next_;
1885 __deallocate_node(__current->__upcast());
1886 __current = __next;
1887 --__size_;
1888
1889 if (__next) {
1890 if (auto __next_chash = std::__constrain_hash(__next->__hash(), __bucket_count); __next_chash != __chash) {
1891 __bucket_list_[__next_chash] = __before_first;
1892 __chash = __next_chash;
1893 break;
1894 }
1895 }
1896 }
19051897 }
1906 __next_pointer __np = __last.__node_;
1907 return iterator(__np);
1898
1899 while (__current != __last_node) {
1900 auto __next = __current->__next_;
1901 __deallocate_node(__current->__upcast());
1902 __current = __next;
1903 --__size_;
1904
1905 // When switching buckets, set the old bucket to be empty and update the next bucket to have __before_first as its
1906 // before-first element
1907 if (__next) {
1908 if (auto __next_chash = std::__constrain_hash(__next->__hash(), __bucket_count); __next_chash != __chash) {
1909 __bucket_list_[__chash] = nullptr;
1910 __bucket_list_[__next_chash] = __before_first;
1911 __chash = __next_chash;
1912 }
1913 } else { // When __next is a nullptr we've fully erased the last bucket. Update the bucket list accordingly.
1914 __bucket_list_[__chash] = nullptr;
1915 }
1916 }
1917
1918 // re-link __before_first with __last
1919 __before_first->__next_ = __current;
1920
1921 return iterator(__last.__node_);
19081922}
19091923
19101924template <class _Tp, class _Hash, class _Equal, class _Alloc>
lib/libcxx/include/__ios/fpos.h+4-4
......@@ -30,7 +30,7 @@ public:
3030
3131 _LIBCPP_HIDE_FROM_ABI operator streamoff() const { return __off_; }
3232
33 _LIBCPP_HIDE_FROM_ABI _StateT state() const { return __st_; }
33 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _StateT state() const { return __st_; }
3434 _LIBCPP_HIDE_FROM_ABI void state(_StateT __st) { __st_ = __st; }
3535
3636 _LIBCPP_HIDE_FROM_ABI fpos& operator+=(streamoff __off) {
......@@ -38,7 +38,7 @@ public:
3838 return *this;
3939 }
4040
41 _LIBCPP_HIDE_FROM_ABI fpos operator+(streamoff __off) const {
41 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI fpos operator+(streamoff __off) const {
4242 fpos __t(*this);
4343 __t += __off;
4444 return __t;
......@@ -49,7 +49,7 @@ public:
4949 return *this;
5050 }
5151
52 _LIBCPP_HIDE_FROM_ABI fpos operator-(streamoff __off) const {
52 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI fpos operator-(streamoff __off) const {
5353 fpos __t(*this);
5454 __t -= __off;
5555 return __t;
......@@ -57,7 +57,7 @@ public:
5757};
5858
5959template <class _StateT>
60inline _LIBCPP_HIDE_FROM_ABI streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y) {
60[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y) {
6161 return streamoff(__x) - streamoff(__y);
6262}
6363
lib/libcxx/include/__iterator/back_insert_iterator.h+1-7
......@@ -26,15 +26,9 @@ _LIBCPP_PUSH_MACROS
2626
2727_LIBCPP_BEGIN_NAMESPACE_STD
2828
29_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3029template <class _Container>
3130class back_insert_iterator
32#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
33 : public iterator<output_iterator_tag, void, void, void, void>
34#endif
35{
36 _LIBCPP_SUPPRESS_DEPRECATED_POP
37
31 : public __iterator_base<back_insert_iterator<_Container>, output_iterator_tag, void, void, void, void> {
3832protected:
3933 _Container* container;
4034
lib/libcxx/include/__iterator/bounded_iter.h+7-8
......@@ -74,12 +74,12 @@ struct __bounded_iter {
7474 _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter const&) = default;
7575 _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter&&) = default;
7676
77 template < class _OtherIterator,
78 __enable_if_t<
79 _And< is_convertible<const _OtherIterator&, _Iterator>,
80 _Or<is_same<reference, __iter_reference<_OtherIterator> >,
81 is_same<reference, __make_const_lvalue_ref<__iter_reference<_OtherIterator> > > > >::value,
82 int> = 0>
77 template <class _OtherIterator,
78 __enable_if_t<
79 _And<is_convertible<const _OtherIterator&, _Iterator>,
80 _Or<is_same<reference, __iterator_reference<_OtherIterator> >,
81 is_same<reference, __make_const_lvalue_ref<__iterator_reference<_OtherIterator> > > > >::value,
82 int> = 0>
8383 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter(__bounded_iter<_OtherIterator> const& __other) _NOEXCEPT
8484 : __current_(__other.__current_),
8585 __begin_(__other.__begin_),
......@@ -116,8 +116,7 @@ public:
116116 // These operations check that the iterator is dereferenceable. Since the class invariant is
117117 // that the iterator is always within `[begin, end]`, we only need to check it's not pointing to
118118 // `end`. This is easier for the optimizer because it aligns with the `iter != container.end()`
119 // checks that typical callers already use (see
120 // https://github.com/llvm/llvm-project/issues/78829).
119 // checks that typical callers already use (see https://llvm.org/PR78829).
121120 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT {
122121 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
123122 __current_ != __end_, "__bounded_iter::operator*: Attempt to dereference an iterator at the end");
lib/libcxx/include/__iterator/concepts.h+6-9
......@@ -117,15 +117,12 @@ template <class _Tp>
117117concept __signed_integer_like = signed_integral<_Tp>;
118118
119119template <class _Ip>
120concept weakly_incrementable =
121 // TODO: remove this once the clang bug is fixed (bugs.llvm.org/PR48173).
122 !same_as<_Ip, bool> && // Currently, clang does not handle bool correctly.
123 movable<_Ip> && requires(_Ip __i) {
124 typename iter_difference_t<_Ip>;
125 requires __signed_integer_like<iter_difference_t<_Ip>>;
126 { ++__i } -> same_as<_Ip&>; // not required to be equality-preserving
127 __i++; // not required to be equality-preserving
128 };
120concept weakly_incrementable = movable<_Ip> && requires(_Ip __i) {
121 typename iter_difference_t<_Ip>;
122 requires __signed_integer_like<iter_difference_t<_Ip>>;
123 { ++__i } -> same_as<_Ip&>; // not required to be equality-preserving
124 __i++; // not required to be equality-preserving
125};
129126
130127// [iterator.concept.inc]
131128template <class _Ip>
lib/libcxx/include/__iterator/cpp17_iterator_concepts.h+13-12
......@@ -68,7 +68,8 @@ concept __cpp17_default_constructible = is_default_constructible_v<_Tp>;
6868template <class _Iter>
6969concept __cpp17_iterator =
7070 __cpp17_copy_constructible<_Iter> && __cpp17_copy_assignable<_Iter> && __cpp17_destructible<_Iter> &&
71 (is_signed_v<__iter_diff_t<_Iter>> || is_void_v<__iter_diff_t<_Iter>>) && requires(_Iter __iter) {
71 (is_signed_v<__iterator_difference_type<_Iter>> || is_void_v<__iterator_difference_type<_Iter>>) &&
72 requires(_Iter __iter) {
7273 { *__iter };
7374 { ++__iter } -> same_as<_Iter&>;
7475 };
......@@ -81,8 +82,8 @@ concept __cpp17_input_iterator =
8182 { __lhs != std::as_const(__rhs) } -> __boolean_testable;
8283 { std::as_const(__lhs) != std::as_const(__rhs) } -> __boolean_testable;
8384
84 { *__lhs } -> same_as<__iter_reference<_Iter>>;
85 { *std::as_const(__lhs) } -> same_as<__iter_reference<_Iter>>;
85 { *__lhs } -> same_as<__iterator_reference<_Iter>>;
86 { *std::as_const(__lhs) } -> same_as<__iterator_reference<_Iter>>;
8687
8788 { ++__lhs } -> same_as<_Iter&>;
8889 { (void)__lhs++ };
......@@ -101,19 +102,19 @@ template <class _Iter>
101102concept __cpp17_forward_iterator =
102103 __cpp17_input_iterator<_Iter> && __cpp17_default_constructible<_Iter> && requires(_Iter __iter) {
103104 { __iter++ } -> convertible_to<const _Iter&>;
104 { *__iter++ } -> same_as<__iter_reference<_Iter>>;
105 { *__iter++ } -> same_as<__iterator_reference<_Iter>>;
105106 };
106107
107108template <class _Iter>
108109concept __cpp17_bidirectional_iterator = __cpp17_forward_iterator<_Iter> && requires(_Iter __iter) {
109110 { --__iter } -> same_as<_Iter&>;
110111 { __iter-- } -> convertible_to<const _Iter&>;
111 { *__iter-- } -> same_as<__iter_reference<_Iter>>;
112 { *__iter-- } -> same_as<__iterator_reference<_Iter>>;
112113};
113114
114115template <class _Iter>
115116concept __cpp17_random_access_iterator =
116 __cpp17_bidirectional_iterator<_Iter> && requires(_Iter __iter, __iter_diff_t<_Iter> __n) {
117 __cpp17_bidirectional_iterator<_Iter> && requires(_Iter __iter, __iterator_difference_type<_Iter> __n) {
117118 { __iter += __n } -> same_as<_Iter&>;
118119
119120 { __iter + __n } -> same_as<_Iter>;
......@@ -125,13 +126,13 @@ concept __cpp17_random_access_iterator =
125126 { __iter - __n } -> same_as<_Iter>;
126127 { std::as_const(__iter) - __n } -> same_as<_Iter>;
127128
128 { __iter - __iter } -> same_as<__iter_diff_t<_Iter>>;
129 { std::as_const(__iter) - __iter } -> same_as<__iter_diff_t<_Iter>>;
130 { __iter - std::as_const(__iter) } -> same_as<__iter_diff_t<_Iter>>;
131 { std::as_const(__iter) - std::as_const(__iter) } -> same_as<__iter_diff_t<_Iter>>;
129 { __iter - __iter } -> same_as<__iterator_difference_type<_Iter>>;
130 { std::as_const(__iter) - __iter } -> same_as<__iterator_difference_type<_Iter>>;
131 { __iter - std::as_const(__iter) } -> same_as<__iterator_difference_type<_Iter>>;
132 { std::as_const(__iter) - std::as_const(__iter) } -> same_as<__iterator_difference_type<_Iter>>;
132133
133 { __iter[__n] } -> convertible_to<__iter_reference<_Iter>>;
134 { std::as_const(__iter)[__n] } -> convertible_to<__iter_reference<_Iter>>;
134 { __iter[__n] } -> convertible_to<__iterator_reference<_Iter>>;
135 { std::as_const(__iter)[__n] } -> convertible_to<__iterator_reference<_Iter>>;
135136
136137 { __iter < __iter } -> __boolean_testable;
137138 { std::as_const(__iter) < __iter } -> __boolean_testable;
lib/libcxx/include/__iterator/distance.h+40-18
......@@ -10,41 +10,66 @@
1010#ifndef _LIBCPP___ITERATOR_DISTANCE_H
1111#define _LIBCPP___ITERATOR_DISTANCE_H
1212
13#include <__algorithm/for_each_segment.h>
14#include <__concepts/same_as.h>
1315#include <__config>
1416#include <__iterator/concepts.h>
1517#include <__iterator/incrementable_traits.h>
1618#include <__iterator/iterator_traits.h>
19#include <__iterator/segmented_iterator.h>
1720#include <__ranges/access.h>
1821#include <__ranges/concepts.h>
1922#include <__ranges/size.h>
2023#include <__type_traits/decay.h>
24#include <__type_traits/enable_if.h>
2125#include <__type_traits/remove_cvref.h>
26#include <__utility/move.h>
2227
2328#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2429# pragma GCC system_header
2530#endif
2631
32_LIBCPP_PUSH_MACROS
33#include <__undef_macros>
34
2735_LIBCPP_BEGIN_NAMESPACE_STD
2836
29template <class _InputIter>
30inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_InputIter>::difference_type
31__distance(_InputIter __first, _InputIter __last, input_iterator_tag) {
32 typename iterator_traits<_InputIter>::difference_type __r(0);
33 for (; __first != __last; ++__first)
34 ++__r;
35 return __r;
36}
37#if _LIBCPP_STD_VER >= 20
38template <class _Iter>
39using __iter_distance_t _LIBCPP_NODEBUG = std::iter_difference_t<_Iter>;
40#else
41template <class _Iter>
42using __iter_distance_t _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::difference_type;
43#endif
3744
38template <class _RandIter>
39inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_RandIter>::difference_type
40__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag) {
45template <class _RandIter, __enable_if_t<__has_random_access_iterator_category<_RandIter>::value, int> = 0>
46inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 __iter_distance_t<_RandIter>
47__distance(_RandIter __first, _RandIter __last) {
4148 return __last - __first;
4249}
4350
51template <class _InputIter, class _Sent>
52inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 __iter_distance_t<_InputIter>
53__distance(_InputIter __first, _Sent __last) {
54 __iter_distance_t<_InputIter> __r(0);
55#if _LIBCPP_STD_VER >= 20
56 if constexpr (same_as<_InputIter, _Sent> && __is_segmented_iterator_v<_InputIter>) {
57 std::__for_each_segment(__first, __last, [&__r](auto __lfirst, auto __llast) {
58 __r += std::__distance(__lfirst, __llast);
59 });
60 } else
61#endif
62 {
63 for (; __first != __last; ++__first)
64 ++__r;
65 }
66 return __r;
67}
68
4469template <class _InputIter>
4570inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_InputIter>::difference_type
4671distance(_InputIter __first, _InputIter __last) {
47 return std::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
72 return std::__distance(__first, __last);
4873}
4974
5075#if _LIBCPP_STD_VER >= 20
......@@ -56,12 +81,7 @@ struct __distance {
5681 template <class _Ip, sentinel_for<_Ip> _Sp>
5782 requires(!sized_sentinel_for<_Sp, _Ip>)
5883 _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip __first, _Sp __last) const {
59 iter_difference_t<_Ip> __n = 0;
60 while (__first != __last) {
61 ++__first;
62 ++__n;
63 }
64 return __n;
84 return std::__distance(std::move(__first), std::move(__last));
6585 }
6686
6787 template <class _Ip, sized_sentinel_for<decay_t<_Ip>> _Sp>
......@@ -92,4 +112,6 @@ inline constexpr auto distance = __distance{};
92112
93113_LIBCPP_END_NAMESPACE_STD
94114
115_LIBCPP_POP_MACROS
116
95117#endif // _LIBCPP___ITERATOR_DISTANCE_H
lib/libcxx/include/__iterator/front_insert_iterator.h+1-7
......@@ -26,15 +26,9 @@ _LIBCPP_PUSH_MACROS
2626
2727_LIBCPP_BEGIN_NAMESPACE_STD
2828
29_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3029template <class _Container>
3130class front_insert_iterator
32#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
33 : public iterator<output_iterator_tag, void, void, void, void>
34#endif
35{
36 _LIBCPP_SUPPRESS_DEPRECATED_POP
37
31 : public __iterator_base<front_insert_iterator<_Container>, output_iterator_tag, void, void, void, void> {
3832protected:
3933 _Container* container;
4034
lib/libcxx/include/__iterator/insert_iterator.h+1-7
......@@ -35,15 +35,9 @@ template <class _Container>
3535using __insert_iterator_iter_t _LIBCPP_NODEBUG = typename _Container::iterator;
3636#endif
3737
38_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3938template <class _Container>
4039class insert_iterator
41#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
42 : public iterator<output_iterator_tag, void, void, void, void>
43#endif
44{
45 _LIBCPP_SUPPRESS_DEPRECATED_POP
46
40 : public __iterator_base<insert_iterator<_Container>, output_iterator_tag, void, void, void, void> {
4741protected:
4842 _Container* container;
4943 __insert_iterator_iter_t<_Container> iter;
lib/libcxx/include/__iterator/istream_iterator.h+6-7
......@@ -25,15 +25,14 @@
2525
2626_LIBCPP_BEGIN_NAMESPACE_STD
2727
28_LIBCPP_SUPPRESS_DEPRECATED_PUSH
2928template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
3029class istream_iterator
31#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
32 : public iterator<input_iterator_tag, _Tp, _Distance, const _Tp*, const _Tp&>
33#endif
34{
35 _LIBCPP_SUPPRESS_DEPRECATED_POP
36
30 : public __iterator_base<istream_iterator<_Tp, _CharT, _Traits, _Distance>,
31 input_iterator_tag,
32 _Tp,
33 _Distance,
34 const _Tp*,
35 const _Tp&> {
3736public:
3837 typedef input_iterator_tag iterator_category;
3938 typedef _Tp value_type;
lib/libcxx/include/__iterator/istreambuf_iterator.h+6-7
......@@ -25,15 +25,14 @@
2525
2626_LIBCPP_BEGIN_NAMESPACE_STD
2727
28_LIBCPP_SUPPRESS_DEPRECATED_PUSH
2928template <class _CharT, class _Traits>
3029class istreambuf_iterator
31#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
32 : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type, _CharT*, _CharT>
33#endif
34{
35 _LIBCPP_SUPPRESS_DEPRECATED_POP
36
30 : public __iterator_base<istreambuf_iterator<_CharT, _Traits>,
31 input_iterator_tag,
32 _CharT,
33 typename _Traits::off_type,
34 _CharT*,
35 _CharT> {
3736public:
3837 typedef input_iterator_tag iterator_category;
3938 typedef _CharT value_type;
lib/libcxx/include/__iterator/iter_move.h+1-1
......@@ -40,7 +40,7 @@ void iter_move() = delete;
4040
4141template <class _Tp>
4242concept __unqualified_iter_move = __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
43 // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap
43 // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_move ADL calls should only be made through ranges::iter_move
4444 iter_move(std::forward<_Tp>(__t));
4545};
4646
lib/libcxx/include/__iterator/iterator.h+13
......@@ -28,6 +28,19 @@ struct _LIBCPP_DEPRECATED_IN_CXX17 iterator {
2828 typedef _Category iterator_category;
2929};
3030
31_LIBCPP_SUPPRESS_DEPRECATED_PUSH
32#ifdef _LIBCPP_ABI_NO_ITERATOR_BASES
33template <class _Derived>
34struct __no_iterator_base {};
35
36template <class _Derived, class _Category, class _Tp, class _Distance, class _Pointer, class _Reference>
37using __iterator_base _LIBCPP_NODEBUG = __no_iterator_base<_Derived>;
38#else
39template <class _Derived, class _Category, class _Tp, class _Distance, class _Pointer, class _Reference>
40using __iterator_base _LIBCPP_NODEBUG = iterator<_Category, _Tp, _Distance, _Pointer, _Reference>;
41#endif
42_LIBCPP_SUPPRESS_DEPRECATED_POP
43
3144_LIBCPP_END_NAMESPACE_STD
3245
3346#endif // _LIBCPP___ITERATOR_ITERATOR_H
lib/libcxx/include/__iterator/iterator_traits.h+13-14
......@@ -420,44 +420,43 @@ using __has_exactly_bidirectional_iterator_category _LIBCPP_NODEBUG =
420420 !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value>;
421421
422422template <class _InputIterator>
423using __iter_value_type _LIBCPP_NODEBUG = typename iterator_traits<_InputIterator>::value_type;
423using __iterator_value_type _LIBCPP_NODEBUG = typename iterator_traits<_InputIterator>::value_type;
424424
425425#if _LIBCPP_STD_VER >= 23
426426template <class _InputIterator>
427using __iter_key_type _LIBCPP_NODEBUG = remove_const_t<tuple_element_t<0, __iter_value_type<_InputIterator>>>;
427using __iter_key_type _LIBCPP_NODEBUG = remove_const_t<tuple_element_t<0, __iterator_value_type<_InputIterator>>>;
428428
429429template <class _InputIterator>
430using __iter_mapped_type _LIBCPP_NODEBUG = tuple_element_t<1, __iter_value_type<_InputIterator>>;
430using __iter_mapped_type _LIBCPP_NODEBUG = tuple_element_t<1, __iterator_value_type<_InputIterator>>;
431431
432432template <class _InputIterator>
433433using __iter_to_alloc_type _LIBCPP_NODEBUG =
434 pair<const tuple_element_t<0, __iter_value_type<_InputIterator>>,
435 tuple_element_t<1, __iter_value_type<_InputIterator>>>;
434 pair<const tuple_element_t<0, __iterator_value_type<_InputIterator>>,
435 tuple_element_t<1, __iterator_value_type<_InputIterator>>>;
436436#else
437437template <class _InputIterator>
438using __iter_key_type _LIBCPP_NODEBUG =
439 __remove_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>;
438using __iter_key_type _LIBCPP_NODEBUG = __remove_const_t<typename __iterator_value_type<_InputIterator>::first_type>;
440439
441440template <class _InputIterator>
442using __iter_mapped_type _LIBCPP_NODEBUG = typename iterator_traits<_InputIterator>::value_type::second_type;
441using __iter_mapped_type _LIBCPP_NODEBUG = typename __iterator_value_type<_InputIterator>::second_type;
443442
444443template <class _InputIterator>
445444using __iter_to_alloc_type _LIBCPP_NODEBUG =
446 pair<const typename iterator_traits<_InputIterator>::value_type::first_type,
447 typename iterator_traits<_InputIterator>::value_type::second_type>;
445 pair<const typename __iterator_value_type<_InputIterator>::first_type,
446 typename __iterator_value_type<_InputIterator>::second_type>;
448447#endif // _LIBCPP_STD_VER >= 23
449448
450449template <class _Iter>
451using __iterator_category_type _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::iterator_category;
450using __iterator_iterator_category _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::iterator_category;
452451
453452template <class _Iter>
454using __iterator_pointer_type _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::pointer;
453using __iterator_pointer _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::pointer;
455454
456455template <class _Iter>
457using __iter_diff_t _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::difference_type;
456using __iterator_difference_type _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::difference_type;
458457
459458template <class _Iter>
460using __iter_reference _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::reference;
459using __iterator_reference _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::reference;
461460
462461#if _LIBCPP_STD_VER >= 20
463462
lib/libcxx/include/__iterator/ostream_iterator.h+1-7
......@@ -24,15 +24,9 @@
2424
2525_LIBCPP_BEGIN_NAMESPACE_STD
2626
27_LIBCPP_SUPPRESS_DEPRECATED_PUSH
2827template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >
2928class ostream_iterator
30#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
31 : public iterator<output_iterator_tag, void, void, void, void>
32#endif
33{
34 _LIBCPP_SUPPRESS_DEPRECATED_POP
35
29 : public __iterator_base<ostream_iterator<_Tp, _CharT, _Traits>, output_iterator_tag, void, void, void, void> {
3630public:
3731 typedef output_iterator_tag iterator_category;
3832 typedef void value_type;
lib/libcxx/include/__iterator/ostreambuf_iterator.h+1-7
......@@ -25,15 +25,9 @@
2525
2626_LIBCPP_BEGIN_NAMESPACE_STD
2727
28_LIBCPP_SUPPRESS_DEPRECATED_PUSH
2928template <class _CharT, class _Traits>
3029class ostreambuf_iterator
31#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
32 : public iterator<output_iterator_tag, void, void, void, void>
33#endif
34{
35 _LIBCPP_SUPPRESS_DEPRECATED_POP
36
30 : public __iterator_base<ostreambuf_iterator<_CharT, _Traits>, output_iterator_tag, void, void, void, void> {
3731public:
3832 typedef output_iterator_tag iterator_category;
3933 typedef void value_type;
lib/libcxx/include/__iterator/reverse_iterator.h+8-13
......@@ -46,21 +46,16 @@
4646
4747_LIBCPP_BEGIN_NAMESPACE_STD
4848
49_LIBCPP_SUPPRESS_DEPRECATED_PUSH
5049template <class _Iter>
5150class reverse_iterator
52#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
53 : public iterator<typename iterator_traits<_Iter>::iterator_category,
54 typename iterator_traits<_Iter>::value_type,
55 typename iterator_traits<_Iter>::difference_type,
56 typename iterator_traits<_Iter>::pointer,
57 typename iterator_traits<_Iter>::reference>
58#endif
59{
60 _LIBCPP_SUPPRESS_DEPRECATED_POP
61
51 : public __iterator_base<reverse_iterator<_Iter>,
52 typename iterator_traits<_Iter>::iterator_category,
53 typename iterator_traits<_Iter>::value_type,
54 typename iterator_traits<_Iter>::difference_type,
55 typename iterator_traits<_Iter>::pointer,
56 typename iterator_traits<_Iter>::reference> {
6257private:
63#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
58#ifndef _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER
6459 _Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break
6560#endif
6661
......@@ -91,7 +86,7 @@ public:
9186 using reference = typename iterator_traits<_Iter>::reference;
9287#endif
9388
94#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
89#ifndef _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER
9590 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator() : __t_(), current() {}
9691
9792 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit reverse_iterator(_Iter __x) : __t_(__x), current(__x) {}
lib/libcxx/include/__iterator/segmented_iterator.h+3-8
......@@ -67,18 +67,13 @@ struct __segmented_iterator_traits;
6767*/
6868
6969template <class _Tp, size_t = 0>
70struct __has_specialization : false_type {};
70inline const bool __has_specialization_v = false;
7171
7272template <class _Tp>
73struct __has_specialization<_Tp, sizeof(_Tp) * 0> : true_type {};
73inline const bool __has_specialization_v<_Tp, sizeof(_Tp) * 0> = true;
7474
7575template <class _Iterator>
76using __is_segmented_iterator _LIBCPP_NODEBUG = __has_specialization<__segmented_iterator_traits<_Iterator> >;
77
78template <class _SegmentedIterator>
79struct __has_random_access_local_iterator
80 : __has_random_access_iterator_category<
81 typename __segmented_iterator_traits< _SegmentedIterator >::__local_iterator > {};
76inline const bool __is_segmented_iterator_v = __has_specialization_v<__segmented_iterator_traits<_Iterator> >;
8277
8378_LIBCPP_END_NAMESPACE_STD
8479
lib/libcxx/include/__iterator/static_bounded_iter.h+3-3
......@@ -99,9 +99,9 @@ struct __static_bounded_iter {
9999
100100 template <class _OtherIterator,
101101 __enable_if_t<
102 _And< is_convertible<const _OtherIterator&, _Iterator>,
103 _Or<is_same<reference, __iter_reference<_OtherIterator> >,
104 is_same<reference, __make_const_lvalue_ref<__iter_reference<_OtherIterator> > > > >::value,
102 _And<is_convertible<const _OtherIterator&, _Iterator>,
103 _Or<is_same<reference, __iterator_reference<_OtherIterator> >,
104 is_same<reference, __make_const_lvalue_ref<__iterator_reference<_OtherIterator> > > > >::value,
105105 int> = 0>
106106 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
107107 __static_bounded_iter(__static_bounded_iter<_OtherIterator, _Size> const& __other) _NOEXCEPT
lib/libcxx/include/__iterator/wrap_iter.h+8-6
......@@ -49,12 +49,12 @@ private:
4949
5050public:
5151 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter() _NOEXCEPT : __i_() {}
52 template <
53 class _OtherIter,
54 __enable_if_t< _And< is_convertible<const _OtherIter&, _Iter>,
55 _Or<is_same<reference, __iter_reference<_OtherIter> >,
56 is_same<reference, __make_const_lvalue_ref<__iter_reference<_OtherIter> > > > >::value,
57 int> = 0>
52 template <class _OtherIter,
53 __enable_if_t<
54 _And<is_convertible<const _OtherIter&, _Iter>,
55 _Or<is_same<reference, __iterator_reference<_OtherIter> >,
56 is_same<reference, __make_const_lvalue_ref<__iterator_reference<_OtherIter> > > > >::value,
57 int> = 0>
5858 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter(const __wrap_iter<_OtherIter>& __u) _NOEXCEPT
5959 : __i_(__u.__i_) {}
6060 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT { return *__i_; }
......@@ -117,6 +117,8 @@ private:
117117 friend class span;
118118 template <class _Tp, size_t _Size>
119119 friend struct array;
120 template <class _Tp, class>
121 friend struct __optional_iterator;
120122};
121123
122124template <class _Iter1>
lib/libcxx/include/__locale+3-10
......@@ -57,9 +57,8 @@ _LIBCPP_HIDE_FROM_ABI const _Facet& use_facet(const locale&);
5757class _LIBCPP_EXPORTED_FROM_ABI locale {
5858public:
5959 // locale is essentially a shared_ptr that doesn't support weak_ptrs and never got a move constructor,
60 // so it is trivially relocatable. Like shared_ptr, it is also replaceable.
60 // so it is trivially relocatable.
6161 using __trivially_relocatable _LIBCPP_NODEBUG = locale;
62 using __replaceable _LIBCPP_NODEBUG = locale;
6362
6463 // types:
6564 class _LIBCPP_EXPORTED_FROM_ABI facet;
......@@ -389,7 +388,7 @@ public:
389388 static const mask xdigit = _ISXDIGIT;
390389 static const mask blank = _ISBLANK;
391390 static const mask __regex_word = 0x8000;
392# elif defined(_NEWLIB_VERSION)
391# elif _LIBCPP_LIBC_NEWLIB
393392 // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
394393 typedef char mask;
395394 // In case char is signed, static_cast is needed to avoid warning on
......@@ -585,7 +584,7 @@ public:
585584# ifdef _CACHED_RUNES
586585 static const size_t table_size = _CACHED_RUNES;
587586# else
588 static const size_t table_size = 256; // FIXME: Don't hardcode this.
587 static const size_t table_size = 256;
589588# endif
590589 _LIBCPP_HIDE_FROM_ABI const mask* table() const _NOEXCEPT { return __tab_; }
591590 static const mask* classic_table() _NOEXCEPT;
......@@ -1478,9 +1477,6 @@ public:
14781477
14791478protected:
14801479 ~numpunct_byname() override;
1481
1482private:
1483 void __init(const char*);
14841480};
14851481
14861482# if _LIBCPP_HAS_WIDE_CHARACTERS
......@@ -1495,9 +1491,6 @@ public:
14951491
14961492protected:
14971493 ~numpunct_byname() override;
1498
1499private:
1500 void __init(const char*);
15011494};
15021495# endif // _LIBCPP_HAS_WIDE_CHARACTERS
15031496
lib/libcxx/include/__locale_dir/locale_base_api.h+5-28
......@@ -57,15 +57,11 @@
5757// float __strtof(const char*, char**, __locale_t);
5858// double __strtod(const char*, char**, __locale_t);
5959// long double __strtold(const char*, char**, __locale_t);
60// long long __strtoll(const char*, char**, __locale_t);
61// unsigned long long __strtoull(const char*, char**, __locale_t);
6260// }
6361//
6462// Character manipulation functions
6563// --------------------------------
6664// namespace __locale {
67// int __isdigit(int, __locale_t); // required by the headers
68// int __isxdigit(int, __locale_t); // required by the headers
6965// int __toupper(int, __locale_t);
7066// int __tolower(int, __locale_t);
7167// int __strcoll(const char*, const char*, __locale_t);
......@@ -106,7 +102,6 @@
106102//
107103// int __snprintf(char*, size_t, __locale_t, const char*, ...); // required by the headers
108104// int __asprintf(char**, __locale_t, const char*, ...); // required by the headers
109// int __sscanf(const char*, __locale_t, const char*, ...); // required by the headers
110105// }
111106
112107#if _LIBCPP_HAS_LOCALIZATION
......@@ -115,7 +110,6 @@
115110# include <__locale_dir/support/apple.h>
116111# elif defined(__FreeBSD__)
117112# include <__locale_dir/support/freebsd.h>
118/* zig patch: https://github.com/llvm/llvm-project/pull/143055 */
119113# elif defined(__NetBSD__)
120114# include <__locale_dir/support/netbsd.h>
121115# elif defined(_LIBCPP_MSVCRT_LIKE)
......@@ -124,20 +118,20 @@
124118# include <__locale_dir/support/fuchsia.h>
125119# elif defined(__linux__)
126120# include <__locale_dir/support/linux.h>
121# elif _LIBCPP_LIBC_NEWLIB
122# include <__locale_dir/support/newlib.h>
123# elif defined(_AIX)
124# include <__locale_dir/support/aix.h>
127125# else
128126
129127// TODO: This is a temporary definition to bridge between the old way we defined the locale base API
130128// (by providing global non-reserved names) and the new API. As we move individual platforms
131129// towards the new way of defining the locale base API, this should disappear since each platform
132130// will define those directly.
133# if defined(_AIX) || defined(__MVS__)
131# if defined(__MVS__)
134132# include <__locale_dir/locale_base_api/ibm.h>
135# elif defined(__ANDROID__)
136# include <__locale_dir/locale_base_api/android.h>
137133# elif defined(__OpenBSD__)
138134# include <__locale_dir/locale_base_api/openbsd.h>
139# elif defined(__wasi__) || _LIBCPP_HAS_MUSL_LIBC
140# include <__locale_dir/locale_base_api/musl.h>
141135# endif
142136
143137# include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
......@@ -197,21 +191,9 @@ inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __
197191 return strtold_l(__nptr, __endptr, __loc);
198192}
199193
200inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
201 return strtoll_l(__nptr, __endptr, __base, __loc);
202}
203
204inline _LIBCPP_HIDE_FROM_ABI unsigned long long
205__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
206 return strtoull_l(__nptr, __endptr, __base, __loc);
207}
208
209194//
210195// Character manipulation functions
211196//
212inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __ch, __locale_t __loc) { return isdigit_l(__ch, __loc); }
213inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __ch, __locale_t __loc) { return isxdigit_l(__ch, __loc); }
214
215197# if defined(_LIBCPP_BUILDING_LIBRARY)
216198inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) {
217199 return strcoll_l(__s1, __s2, __loc);
......@@ -307,11 +289,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __
307289 char** __s, __locale_t __loc, const char* __format, _Args&&... __args) {
308290 return std::__libcpp_asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
309291}
310template <class... _Args>
311_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
312 const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) {
313 return std::__libcpp_sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
314}
315292_LIBCPP_DIAGNOSTIC_POP
316293# undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
317294
lib/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h-10
......@@ -125,16 +125,6 @@ inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __libcpp_asprintf_l(
125125 return __res;
126126}
127127
128inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __libcpp_sscanf_l(
129 const char* __s, locale_t __l, const char* __format, ...) {
130 va_list __va;
131 va_start(__va, __format);
132 __locale_guard __current(__l);
133 int __res = vsscanf(__s, __format, __va);
134 va_end(__va);
135 return __res;
136}
137
138128_LIBCPP_END_NAMESPACE_STD
139129
140130#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
lib/libcxx/include/__locale_dir/messages.h+1-1
......@@ -22,7 +22,7 @@
2222
2323# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
2424// Most unix variants have catopen. These are the specific ones that don't.
25# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__)
25# if !defined(__BIONIC__) && !_LIBCPP_LIBC_NEWLIB && !defined(__EMSCRIPTEN__)
2626# define _LIBCPP_HAS_CATOPEN 1
2727# include <nl_types.h>
2828# else
lib/libcxx/include/__locale_dir/money.h+2-2
......@@ -433,7 +433,7 @@ bool money_get<_CharT, _InputIterator>::__do_get(
433433 __err |= ios_base::failbit;
434434 return false;
435435 }
436 for (++__b; __fd > 0; --__fd, ++__b) {
436 for (++__b; __fd > 0; --__fd, (void)++__b) {
437437 if (__b == __e || !__ct.is(ctype_base::digit, *__b)) {
438438 __err |= ios_base::failbit;
439439 return false;
......@@ -451,7 +451,7 @@ bool money_get<_CharT, _InputIterator>::__do_get(
451451 }
452452 }
453453 if (__trailing_sign) {
454 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b) {
454 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, (void)++__b) {
455455 if (__b == __e || *__b != (*__trailing_sign)[__i]) {
456456 __err |= ios_base::failbit;
457457 return false;
lib/libcxx/include/__locale_dir/num.h+190-243
......@@ -9,8 +9,10 @@
99#ifndef _LIBCPP___LOCALE_DIR_NUM_H
1010#define _LIBCPP___LOCALE_DIR_NUM_H
1111
12#include <__algorithm/copy.h>
1213#include <__algorithm/find.h>
1314#include <__algorithm/reverse.h>
15#include <__algorithm/simd_utils.h>
1416#include <__charconv/to_chars_integral.h>
1517#include <__charconv/traits.h>
1618#include <__config>
......@@ -22,6 +24,7 @@
2224#include <__locale_dir/scan_keyword.h>
2325#include <__memory/unique_ptr.h>
2426#include <__system_error/errc.h>
27#include <__type_traits/is_signed.h>
2528#include <cerrno>
2629#include <ios>
2730#include <streambuf>
......@@ -46,9 +49,9 @@ struct _LIBCPP_EXPORTED_FROM_ABI __num_get_base {
4649 static int __get_base(ios_base&);
4750 static const char __src[33]; // "0123456789abcdefABCDEFxX+-pPiInN"
4851 // count of leading characters in __src used for parsing integers ("012..X+-")
49 static const size_t __int_chr_cnt = 26;
52 static inline const size_t __int_chr_cnt = 26;
5053 // count of leading characters in __src used for parsing floating-point values ("012..-pP")
51 static const size_t __fp_chr_cnt = 28;
54 static inline const size_t __fp_chr_cnt = 28;
5255};
5356
5457template <class _CharT>
......@@ -71,7 +74,8 @@ struct __num_get : protected __num_get_base {
7174
7275 [[__deprecated__("This exists only for ABI compatibility")]] static string
7376 __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
74 static int __stage2_int_loop(
77
78 [[__deprecated__("This exists only for ABI compatibility")]] static int __stage2_int_loop(
7579 _CharT __ct,
7680 int __base,
7781 char* __a,
......@@ -83,11 +87,24 @@ struct __num_get : protected __num_get_base {
8387 unsigned*& __g_end,
8488 _CharT* __atoms);
8589
86 _LIBCPP_HIDE_FROM_ABI static string __stage2_int_prep(ios_base& __iob, _CharT& __thousands_sep) {
87 locale __loc = __iob.getloc();
88 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
89 __thousands_sep = __np.thousands_sep();
90 return __np.grouping();
90 _LIBCPP_HIDE_FROM_ABI static ptrdiff_t __atoms_offset(const _CharT* __atoms, _CharT __val) {
91 // TODO: Remove the manual vectorization once https://llvm.org/PR168551 is resolved
92# if _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS
93 if constexpr (is_same<_CharT, char>::value) {
94 // TODO(LLVM 24): This can be removed, since -Wpsabi doesn't warn on [[gnu::always_inline]] functions anymore.
95 _LIBCPP_DIAGNOSTIC_PUSH
96 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpsabi")
97 using __vec = __simd_vector<char, 32>;
98 __vec __chars = std::__broadcast<__vec>(__val);
99 __vec __cmp = std::__partial_load<__vec, __int_chr_cnt>(__atoms);
100 auto __res = __chars == __cmp;
101 if (std::__none_of(__res))
102 return __int_chr_cnt;
103 return std::min(__int_chr_cnt, std::__find_first_set(__res));
104 _LIBCPP_DIAGNOSTIC_POP
105 }
106# endif
107 return std::find(__atoms, __atoms + __int_chr_cnt, __val) - __atoms;
91108 }
92109
93110 _LIBCPP_HIDE_FROM_ABI const _CharT* __do_widen(ios_base& __iob, _CharT* __atoms) const {
......@@ -120,54 +137,6 @@ string __num_get<_CharT>::__stage2_float_prep(
120137 return __np.grouping();
121138}
122139
123template <class _CharT>
124int __num_get<_CharT>::__stage2_int_loop(
125 _CharT __ct,
126 int __base,
127 char* __a,
128 char*& __a_end,
129 unsigned& __dc,
130 _CharT __thousands_sep,
131 const string& __grouping,
132 unsigned* __g,
133 unsigned*& __g_end,
134 _CharT* __atoms) {
135 if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) {
136 *__a_end++ = __ct == __atoms[24] ? '+' : '-';
137 __dc = 0;
138 return 0;
139 }
140 if (__grouping.size() != 0 && __ct == __thousands_sep) {
141 if (__g_end - __g < __num_get_buf_sz) {
142 *__g_end++ = __dc;
143 __dc = 0;
144 }
145 return 0;
146 }
147 ptrdiff_t __f = std::find(__atoms, __atoms + __int_chr_cnt, __ct) - __atoms;
148 if (__f >= 24)
149 return -1;
150 switch (__base) {
151 case 8:
152 case 10:
153 if (__f >= __base)
154 return -1;
155 break;
156 case 16:
157 if (__f < 22)
158 break;
159 if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') {
160 __dc = 0;
161 *__a_end++ = __src[__f];
162 return 0;
163 }
164 return -1;
165 }
166 *__a_end++ = __src[__f];
167 ++__dc;
168 return 0;
169}
170
171140template <class _CharT>
172141int __num_get<_CharT>::__stage2_float_loop(
173142 _CharT __ct,
......@@ -272,65 +241,6 @@ _LIBCPP_HIDE_FROM_ABI _Tp __num_get_float(const char* __a, const char* __a_end,
272241 return 0;
273242}
274243
275template <class _Tp>
276_LIBCPP_HIDE_FROM_ABI _Tp
277__num_get_signed_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) {
278 if (__a != __a_end) {
279 __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno;
280 errno = 0;
281 char* __p2;
282 long long __ll = __locale::__strtoll(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
283 __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
284 if (__current_errno == 0)
285 errno = __save_errno;
286 if (__p2 != __a_end) {
287 __err = ios_base::failbit;
288 return 0;
289 } else if (__current_errno == ERANGE || __ll < numeric_limits<_Tp>::min() || numeric_limits<_Tp>::max() < __ll) {
290 __err = ios_base::failbit;
291 if (__ll > 0)
292 return numeric_limits<_Tp>::max();
293 else
294 return numeric_limits<_Tp>::min();
295 }
296 return static_cast<_Tp>(__ll);
297 }
298 __err = ios_base::failbit;
299 return 0;
300}
301
302template <class _Tp>
303_LIBCPP_HIDE_FROM_ABI _Tp
304__num_get_unsigned_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) {
305 if (__a != __a_end) {
306 const bool __negate = *__a == '-';
307 if (__negate && ++__a == __a_end) {
308 __err = ios_base::failbit;
309 return 0;
310 }
311 __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno;
312 errno = 0;
313 char* __p2;
314 unsigned long long __ll = __locale::__strtoull(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
315 __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
316 if (__current_errno == 0)
317 errno = __save_errno;
318 if (__p2 != __a_end) {
319 __err = ios_base::failbit;
320 return 0;
321 } else if (__current_errno == ERANGE || numeric_limits<_Tp>::max() < __ll) {
322 __err = ios_base::failbit;
323 return numeric_limits<_Tp>::max();
324 }
325 _Tp __res = static_cast<_Tp>(__ll);
326 if (__negate)
327 __res = -__res;
328 return __res;
329 }
330 __err = ios_base::failbit;
331 return 0;
332}
333
334244template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
335245class num_get : public locale::facet, private __num_get<_CharT> {
336246public:
......@@ -468,137 +378,196 @@ protected:
468378 return __b;
469379 }
470380
471 template <class _Signed>
472 _LIBCPP_HIDE_FROM_ABI iter_type
473 __do_get_signed(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Signed& __v) const {
381 template <class _MaybeSigned>
382 iter_type __do_get_integral(
383 iter_type __first, iter_type __last, ios_base& __iob, ios_base::iostate& __err, _MaybeSigned& __v) const {
384 using _Unsigned = __make_unsigned_t<_MaybeSigned>;
385
474386 // Stage 1
475387 int __base = this->__get_base(__iob);
476 // Stage 2
477 char_type __thousands_sep;
478 const int __atoms_size = __num_get_base::__int_chr_cnt;
479 char_type __atoms1[__atoms_size];
480 const char_type* __atoms = this->__do_widen(__iob, __atoms1);
481 string __grouping = this->__stage2_int_prep(__iob, __thousands_sep);
482 string __buf;
483 __buf.resize(__buf.capacity());
484 char* __a = &__buf[0];
485 char* __a_end = __a;
388
389 // Stages 2 & 3
390 // These are combined into a single step where we parse the characters and calculate the value in one go instead of
391 // storing the relevant characters first (in an allocated buffer) and parse the characters after we extracted them.
392 // This makes the whole process significantly faster, since we avoid potential allocations and copies.
393
394 const auto& __numpunct = use_facet<numpunct<_CharT> >(__iob.getloc());
395 char_type __thousands_sep = __numpunct.thousands_sep();
396 string __grouping = __numpunct.grouping();
397
398 char_type __atoms_buffer[__num_get_base::__int_chr_cnt];
399 const char_type* __atoms = this->__do_widen(__iob, __atoms_buffer);
486400 unsigned __g[__num_get_base::__num_get_buf_sz];
487401 unsigned* __g_end = __g;
488402 unsigned __dc = 0;
489 for (; __b != __e; ++__b) {
490 if (__a_end == __a + __buf.size()) {
491 size_t __tmp = __buf.size();
492 __buf.resize(2 * __buf.size());
493 __buf.resize(__buf.capacity());
494 __a = &__buf[0];
495 __a_end = __a + __tmp;
403
404 if (__first == __last) {
405 __err |= ios_base::eofbit | ios_base::failbit;
406 __v = 0;
407 return __first;
408 }
409
410 while (!__grouping.empty() && *__first == __thousands_sep) {
411 ++__first;
412 if (__g_end - __g < this->__num_get_buf_sz)
413 *__g_end++ = 0;
414 }
415
416 bool __negate = false;
417 // __c == '+' || __c == '-'
418 if (auto __c = *__first; __c == __atoms[24] || __c == __atoms[25]) {
419 __negate = __c == __atoms[25];
420 ++__first;
421 }
422
423 if (__first == __last) {
424 __err |= ios_base::eofbit | ios_base::failbit;
425 __v = 0;
426 return __first;
427 }
428
429 bool __parsed_num = false;
430
431 // If we don't have a pre-set base, figure it out and swallow any prefix
432 if (__base == 0) {
433 auto __c = *__first;
434 // __c == '0'
435 if (__c == __atoms[0]) {
436 ++__first;
437 if (__first == __last) {
438 __err |= ios_base::eofbit;
439 __v = 0;
440 return __first;
441 }
442 // __c2 == 'x' || __c2 == 'X'
443 if (auto __c2 = *__first; __c2 == __atoms[22] || __c2 == __atoms[23]) {
444 __base = 16;
445 ++__first;
446 } else {
447 __base = 8;
448 __parsed_num = true; // We only swallowed '0', so we've started to parse a number
449 }
450 } else {
451 __base = 10;
452 }
453
454 // If the base has been specified explicitly, try to swallow the appropriate prefix. We only need to do something
455 // special for hex, since decimal has no prefix and octal's prefix is '0', which doesn't change the value that
456 // we'll parse if we don't swallow it.
457 } else if (__base == 16) {
458 // Try to swallow '0x'
459
460 // *__first == '0'
461 if (*__first == __atoms[0]) {
462 ++__first;
463 if (__first == __last) {
464 __err |= ios_base::eofbit;
465 __v = 0;
466 return __first;
467 }
468 // __c == 'x' || __c == 'X'
469 if (auto __c = *__first; __c == __atoms[22] || __c == __atoms[23])
470 ++__first;
471 else
472 __parsed_num = true; // We only swallowed '0', so we've started to parse a number
496473 }
497 if (this->__stage2_int_loop(
498 *__b,
499 __base,
500 __a,
501 __a_end,
502 __dc,
503 __thousands_sep,
504 __grouping,
505 __g,
506 __g_end,
507 const_cast<char_type*>(__atoms)))
508 break;
509474 }
510 if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz)
511 *__g_end++ = __dc;
512 // Stage 3
513 __v = std::__num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
514 // Digit grouping checked
515 __check_grouping(__grouping, __g, __g_end, __err);
516 // EOF checked
517 if (__b == __e)
518 __err |= ios_base::eofbit;
519 return __b;
520 }
521475
522 template <class _Unsigned>
523 _LIBCPP_HIDE_FROM_ABI iter_type
524 __do_get_unsigned(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Unsigned& __v) const {
525 // Stage 1
526 int __base = this->__get_base(__iob);
527 // Stage 2
528 char_type __thousands_sep;
529 const int __atoms_size = __num_get_base::__int_chr_cnt;
530 char_type __atoms1[__atoms_size];
531 const char_type* __atoms = this->__do_widen(__iob, __atoms1);
532 string __grouping = this->__stage2_int_prep(__iob, __thousands_sep);
533 string __buf;
534 __buf.resize(__buf.capacity());
535 char* __a = &__buf[0];
536 char* __a_end = __a;
537 unsigned __g[__num_get_base::__num_get_buf_sz];
538 unsigned* __g_end = __g;
539 unsigned __dc = 0;
540 for (; __b != __e; ++__b) {
541 if (__a_end == __a + __buf.size()) {
542 size_t __tmp = __buf.size();
543 __buf.resize(2 * __buf.size());
544 __buf.resize(__buf.capacity());
545 __a = &__buf[0];
546 __a_end = __a + __tmp;
476 // Calculate the actual number
477 _Unsigned __val = 0;
478 bool __overflowed = false;
479 for (; __first != __last; ++__first) {
480 auto __c = *__first;
481 if (!__grouping.empty() && __c == __thousands_sep) {
482 if (__g_end - __g < this->__num_get_buf_sz) {
483 *__g_end++ = __dc;
484 __dc = 0;
485 }
486 continue;
547487 }
548 if (this->__stage2_int_loop(
549 *__b,
550 __base,
551 __a,
552 __a_end,
553 __dc,
554 __thousands_sep,
555 __grouping,
556 __g,
557 __g_end,
558 const_cast<char_type*>(__atoms)))
488 auto __offset = this->__atoms_offset(__atoms, __c);
489 if (__offset >= 22) // Not a valid integer character
490 break;
491
492 if (__base == 16 && __offset >= 16)
493 __offset -= 6;
494 if (__offset >= __base)
559495 break;
496 // __val = (__val * __base) + __offset
497 __overflowed |= __builtin_mul_overflow(__val, __base, std::addressof(__val)) ||
498 __builtin_add_overflow(__val, __offset, std::addressof(__val));
499 __parsed_num = true;
500 ++__dc;
501 }
502
503 if (!__parsed_num) {
504 __err |= ios_base::failbit;
505 __v = 0;
506 } else if (__overflowed) {
507 __err |= ios_base::failbit;
508 __v = is_signed<_MaybeSigned>::value && __negate
509 ? numeric_limits<_MaybeSigned>::min()
510 : numeric_limits<_MaybeSigned>::max();
511 } else if (!__negate) {
512 if (__val > static_cast<_Unsigned>(numeric_limits<_MaybeSigned>::max())) {
513 __err |= ios_base::failbit;
514 __v = numeric_limits<_MaybeSigned>::max();
515 } else {
516 __v = __val;
517 }
518 } else if (is_signed<_MaybeSigned>::value) {
519 if (__val > static_cast<_Unsigned>(numeric_limits<_MaybeSigned>::max()) + 1) {
520 __err |= ios_base::failbit;
521 __v = numeric_limits<_MaybeSigned>::min();
522 } else if (__val == static_cast<_Unsigned>(numeric_limits<_MaybeSigned>::max()) + 1) {
523 __v = numeric_limits<_MaybeSigned>::min();
524 } else {
525 __v = -__val;
526 }
527 } else {
528 __v = -__val;
560529 }
530
561531 if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz)
562532 *__g_end++ = __dc;
563 // Stage 3
564 __v = std::__num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
533
565534 // Digit grouping checked
566535 __check_grouping(__grouping, __g, __g_end, __err);
567536 // EOF checked
568 if (__b == __e)
537 if (__first == __last)
569538 __err |= ios_base::eofbit;
570 return __b;
539 return __first;
571540 }
572541
573542 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, bool& __v) const;
574543
575544 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long& __v) const {
576 return this->__do_get_signed(__b, __e, __iob, __err, __v);
545 return this->__do_get_integral(__b, __e, __iob, __err, __v);
577546 }
578547
579548 virtual iter_type
580549 do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long long& __v) const {
581 return this->__do_get_signed(__b, __e, __iob, __err, __v);
550 return this->__do_get_integral(__b, __e, __iob, __err, __v);
582551 }
583552
584553 virtual iter_type
585554 do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned short& __v) const {
586 return this->__do_get_unsigned(__b, __e, __iob, __err, __v);
555 return this->__do_get_integral(__b, __e, __iob, __err, __v);
587556 }
588557
589558 virtual iter_type
590559 do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned int& __v) const {
591 return this->__do_get_unsigned(__b, __e, __iob, __err, __v);
560 return this->__do_get_integral(__b, __e, __iob, __err, __v);
592561 }
593562
594563 virtual iter_type
595564 do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long& __v) const {
596 return this->__do_get_unsigned(__b, __e, __iob, __err, __v);
565 return this->__do_get_integral(__b, __e, __iob, __err, __v);
597566 }
598567
599568 virtual iter_type
600569 do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long long& __v) const {
601 return this->__do_get_unsigned(__b, __e, __iob, __err, __v);
570 return this->__do_get_integral(__b, __e, __iob, __err, __v);
602571 }
603572
604573 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, float& __v) const {
......@@ -652,40 +621,13 @@ _InputIterator num_get<_CharT, _InputIterator>::do_get(
652621template <class _CharT, class _InputIterator>
653622_InputIterator num_get<_CharT, _InputIterator>::do_get(
654623 iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, void*& __v) const {
655 // Stage 1
656 int __base = 16;
657 // Stage 2
658 char_type __atoms[__num_get_base::__int_chr_cnt];
659 char_type __thousands_sep = char_type();
660 string __grouping;
661 std::use_facet<ctype<_CharT> >(__iob.getloc())
662 .widen(__num_get_base::__src, __num_get_base::__src + __num_get_base::__int_chr_cnt, __atoms);
663 string __buf;
664 __buf.resize(__buf.capacity());
665 char* __a = &__buf[0];
666 char* __a_end = __a;
667 unsigned __g[__num_get_base::__num_get_buf_sz];
668 unsigned* __g_end = __g;
669 unsigned __dc = 0;
670 for (; __b != __e; ++__b) {
671 if (__a_end == __a + __buf.size()) {
672 size_t __tmp = __buf.size();
673 __buf.resize(2 * __buf.size());
674 __buf.resize(__buf.capacity());
675 __a = &__buf[0];
676 __a_end = __a + __tmp;
677 }
678 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, __thousands_sep, __grouping, __g, __g_end, __atoms))
679 break;
680 }
681 // Stage 3
682 __buf.resize(__a_end - __a);
683 if (__locale::__sscanf(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
684 __err = ios_base::failbit;
685 // EOF checked
686 if (__b == __e)
687 __err |= ios_base::eofbit;
688 return __b;
624 auto __flags = __iob.flags();
625 __iob.flags((__flags & ~ios_base::basefield & ~ios_base::uppercase) | ios_base::hex);
626 uintptr_t __ptr;
627 auto __res = __do_get_integral(__b, __e, __iob, __err, __ptr);
628 __iob.flags(__flags);
629 __v = reinterpret_cast<void*>(__ptr);
630 return __res;
689631}
690632
691633extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>;
......@@ -748,6 +690,13 @@ void __num_put<_CharT>::__widen_and_group_int(
748690 __op = __ob + (__np - __nb);
749691}
750692
693_LIBCPP_HIDE_FROM_ABI inline bool __isdigit(char __c) { return __c >= '0' && __c <= '9'; }
694
695_LIBCPP_HIDE_FROM_ABI inline bool __isxdigit(char __c) {
696 auto __lower = __c | 0x20;
697 return std::__isdigit(__c) || (__lower >= 'a' && __lower <= 'f');
698}
699
751700template <class _CharT>
752701void __num_put<_CharT>::__widen_and_group_float(
753702 char* __nb, char* __np, char* __ne, _CharT* __ob, _CharT*& __op, _CharT*& __oe, const locale& __loc) {
......@@ -763,11 +712,11 @@ void __num_put<_CharT>::__widen_and_group_float(
763712 *__oe++ = __ct.widen(*__nf++);
764713 *__oe++ = __ct.widen(*__nf++);
765714 for (__ns = __nf; __ns < __ne; ++__ns)
766 if (!__locale::__isxdigit(*__ns, _LIBCPP_GET_C_LOCALE))
715 if (!std::__isxdigit(*__ns))
767716 break;
768717 } else {
769718 for (__ns = __nf; __ns < __ne; ++__ns)
770 if (!__locale::__isdigit(*__ns, _LIBCPP_GET_C_LOCALE))
719 if (!std::__isdigit(*__ns))
771720 break;
772721 }
773722 if (__grouping.empty()) {
......@@ -885,9 +834,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char_ty
885834 const numpunct<char_type>& __np = std::use_facet<numpunct<char_type> >(__iob.getloc());
886835 typedef typename numpunct<char_type>::string_type string_type;
887836 string_type __nm = __v ? __np.truename() : __np.falsename();
888 for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
889 *__s = *__i;
890 return __s;
837 return std::copy(__nm.begin(), __nm.end(), __s);
891838}
892839
893840template <class _CharT, class _OutputIterator>
lib/libcxx/include/__locale_dir/pad_and_output.h+5-6
......@@ -13,6 +13,8 @@
1313
1414#if _LIBCPP_HAS_LOCALIZATION
1515
16# include <__algorithm/copy.h>
17# include <__algorithm/fill_n.h>
1618# include <ios>
1719
1820# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -30,12 +32,9 @@ _LIBCPP_HIDE_FROM_ABI _OutputIterator __pad_and_output(
3032 __ns -= __sz;
3133 else
3234 __ns = 0;
33 for (; __ob < __op; ++__ob, ++__s)
34 *__s = *__ob;
35 for (; __ns; --__ns, ++__s)
36 *__s = __fl;
37 for (; __ob < __oe; ++__ob, ++__s)
38 *__s = *__ob;
35 __s = std::copy(__ob, __op, __s);
36 __s = std::fill_n(__s, __ns, __fl);
37 __s = std::copy(__op, __oe, __s);
3938 __iob.width(0);
4039 return __s;
4140}
lib/libcxx/include/__locale_dir/support/bsd_like.h-20
......@@ -24,7 +24,6 @@
2424# include <wctype.h>
2525#endif
2626
27/* zig patch: https://github.com/llvm/llvm-project/pull/143055 */
2827#if __has_include(<xlocale.h>)
2928# include <xlocale.h>
3029#endif
......@@ -80,22 +79,9 @@ inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __
8079 return ::strtold_l(__nptr, __endptr, __loc);
8180}
8281
83inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
84 return ::strtoll_l(__nptr, __endptr, __base, __loc);
85}
86
87inline _LIBCPP_HIDE_FROM_ABI unsigned long long
88__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
89 return ::strtoull_l(__nptr, __endptr, __base, __loc);
90}
91
9282//
9383// Character manipulation functions
9484//
95inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return ::isdigit_l(__c, __loc); }
96
97inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return ::isxdigit_l(__c, __loc); }
98
9985#if defined(_LIBCPP_BUILDING_LIBRARY)
10086inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return ::toupper_l(__c, __loc); }
10187
......@@ -216,12 +202,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __
216202 char** __s, __locale_t __loc, const char* __format, _Args&&... __args) {
217203 return ::asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...); // non-standard
218204}
219
220template <class... _Args>
221_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
222 const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) {
223 return ::sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
224}
225205_LIBCPP_DIAGNOSTIC_POP
226206#undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
227207
lib/libcxx/include/__locale_dir/support/fuchsia.h-7
......@@ -141,13 +141,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __
141141 __locale_guard __current(__loc);
142142 return ::asprintf(__s, __format, std::forward<_Args>(__args)...); // non-standard
143143}
144template <class... _Args>
145_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
146 const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) {
147 __locale_guard __current(__loc);
148 return std::sscanf(__s, __format, std::forward<_Args>(__args)...);
149}
150
151144_LIBCPP_DIAGNOSTIC_POP
152145#undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
153146
lib/libcxx/include/__locale_dir/support/linux.h-37
......@@ -94,32 +94,9 @@ inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __
9494 return ::strtold_l(__nptr, __endptr, __loc);
9595}
9696
97inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
98#if !_LIBCPP_HAS_MUSL_LIBC
99 return ::strtoll_l(__nptr, __endptr, __base, __loc);
100#else
101 (void)__loc;
102 return ::strtoll(__nptr, __endptr, __base);
103#endif
104}
105
106inline _LIBCPP_HIDE_FROM_ABI unsigned long long
107__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
108#if !_LIBCPP_HAS_MUSL_LIBC
109 return ::strtoull_l(__nptr, __endptr, __base, __loc);
110#else
111 (void)__loc;
112 return ::strtoull(__nptr, __endptr, __base);
113#endif
114}
115
11697//
11798// Character manipulation functions
11899//
119inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return isdigit_l(__c, __loc); }
120
121inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return isxdigit_l(__c, __loc); }
122
123100#if defined(_LIBCPP_BUILDING_LIBRARY)
124101inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return toupper_l(__c, __loc); }
125102
......@@ -261,20 +238,6 @@ inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf(
261238 va_end(__va);
262239 return __res;
263240}
264
265#ifndef _LIBCPP_COMPILER_GCC // GCC complains that this can't be always_inline due to C-style varargs
266_LIBCPP_HIDE_FROM_ABI
267#endif
268inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
269 const char* __s, __locale_t __loc, const char* __format, ...) {
270 va_list __va;
271 va_start(__va, __format);
272 __locale_guard __current(__loc);
273 int __res = std::vsscanf(__s, __format, __va);
274 va_end(__va);
275 return __res;
276}
277
278241} // namespace __locale
279242_LIBCPP_END_NAMESPACE_STD
280243
lib/libcxx/include/__locale_dir/support/netbsd.h-2
......@@ -6,8 +6,6 @@
66//
77//===----------------------------------------------------------------------===//
88
9/* zig patch: https://github.com/llvm/llvm-project/pull/143055 */
10
119#ifndef _LIBCPP___LOCALE_DIR_SUPPORT_NETBSD_H
1210#define _LIBCPP___LOCALE_DIR_SUPPORT_NETBSD_H
1311
lib/libcxx/include/__locale_dir/support/newlib.h created+243
......@@ -0,0 +1,243 @@
1//===-----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___LOCALE_DIR_SUPPORT_NEWLIB_H
10#define _LIBCPP___LOCALE_DIR_SUPPORT_NEWLIB_H
11
12#include <__config>
13#include <__cstddef/size_t.h>
14#include <__std_mbstate_t.h>
15#include <clocale> // std::lconv
16#include <cstdio>
17#include <cstdlib>
18#include <ctype.h>
19#include <stdarg.h>
20#include <string.h>
21#include <time.h>
22#if _LIBCPP_HAS_WIDE_CHARACTERS
23# include <cwchar>
24# include <wctype.h>
25#endif
26
27#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
28# pragma GCC system_header
29#endif
30
31_LIBCPP_BEGIN_NAMESPACE_STD
32namespace __locale {
33
34struct __locale_guard {
35 _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t& __loc) : __old_loc_(::uselocale(__loc)) {}
36
37 _LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
38 if (__old_loc_)
39 ::uselocale(__old_loc_);
40 }
41
42 locale_t __old_loc_;
43
44 __locale_guard(__locale_guard const&) = delete;
45 __locale_guard& operator=(__locale_guard const&) = delete;
46};
47
48//
49// Locale management
50//
51#define _LIBCPP_COLLATE_MASK LC_COLLATE_MASK
52#define _LIBCPP_CTYPE_MASK LC_CTYPE_MASK
53#define _LIBCPP_MONETARY_MASK LC_MONETARY_MASK
54#define _LIBCPP_NUMERIC_MASK LC_NUMERIC_MASK
55#define _LIBCPP_TIME_MASK LC_TIME_MASK
56#define _LIBCPP_MESSAGES_MASK LC_MESSAGES_MASK
57#define _LIBCPP_ALL_MASK LC_ALL_MASK
58#define _LIBCPP_LC_ALL LC_ALL
59
60using __locale_t _LIBCPP_NODEBUG = ::locale_t;
61
62#if defined(_LIBCPP_BUILDING_LIBRARY)
63using __lconv_t _LIBCPP_NODEBUG = std::lconv;
64
65inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __locale, __locale_t __base) {
66 return ::newlocale(__category_mask, __locale, __base);
67}
68
69inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { ::freelocale(__loc); }
70
71inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, char const* __locale) {
72 return ::setlocale(__category, __locale);
73}
74
75inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) {
76 __locale_guard __current(__loc);
77 return std::localeconv();
78}
79#endif // _LIBCPP_BUILDING_LIBRARY
80
81//
82// Strtonum functions
83//
84inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) {
85 return ::strtof_l(__nptr, __endptr, __loc);
86}
87
88inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) {
89 return ::strtod_l(__nptr, __endptr, __loc);
90}
91
92inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) {
93 return ::strtold_l(__nptr, __endptr, __loc);
94}
95
96//
97// Character manipulation functions
98//
99#if defined(_LIBCPP_BUILDING_LIBRARY)
100inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return toupper_l(__c, __loc); }
101
102inline _LIBCPP_HIDE_FROM_ABI int __tolower(int __c, __locale_t __loc) { return tolower_l(__c, __loc); }
103
104inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) {
105 return strcoll_l(__s1, __s2, __loc);
106}
107
108inline _LIBCPP_HIDE_FROM_ABI size_t __strxfrm(char* __dest, const char* __src, size_t __n, __locale_t __loc) {
109 return strxfrm_l(__dest, __src, __n, __loc);
110}
111
112# if _LIBCPP_HAS_WIDE_CHARACTERS
113inline _LIBCPP_HIDE_FROM_ABI int __iswctype(wint_t __c, wctype_t __type, __locale_t __loc) {
114 return iswctype_l(__c, __type, __loc);
115}
116
117inline _LIBCPP_HIDE_FROM_ABI int __iswspace(wint_t __c, __locale_t __loc) { return iswspace_l(__c, __loc); }
118
119inline _LIBCPP_HIDE_FROM_ABI int __iswprint(wint_t __c, __locale_t __loc) { return iswprint_l(__c, __loc); }
120
121inline _LIBCPP_HIDE_FROM_ABI int __iswcntrl(wint_t __c, __locale_t __loc) { return iswcntrl_l(__c, __loc); }
122
123inline _LIBCPP_HIDE_FROM_ABI int __iswupper(wint_t __c, __locale_t __loc) { return iswupper_l(__c, __loc); }
124
125inline _LIBCPP_HIDE_FROM_ABI int __iswlower(wint_t __c, __locale_t __loc) { return iswlower_l(__c, __loc); }
126
127inline _LIBCPP_HIDE_FROM_ABI int __iswalpha(wint_t __c, __locale_t __loc) { return iswalpha_l(__c, __loc); }
128
129inline _LIBCPP_HIDE_FROM_ABI int __iswblank(wint_t __c, __locale_t __loc) { return iswblank_l(__c, __loc); }
130
131inline _LIBCPP_HIDE_FROM_ABI int __iswdigit(wint_t __c, __locale_t __loc) { return iswdigit_l(__c, __loc); }
132
133inline _LIBCPP_HIDE_FROM_ABI int __iswpunct(wint_t __c, __locale_t __loc) { return iswpunct_l(__c, __loc); }
134
135inline _LIBCPP_HIDE_FROM_ABI int __iswxdigit(wint_t __c, __locale_t __loc) { return iswxdigit_l(__c, __loc); }
136
137inline _LIBCPP_HIDE_FROM_ABI wint_t __towupper(wint_t __c, __locale_t __loc) { return towupper_l(__c, __loc); }
138
139inline _LIBCPP_HIDE_FROM_ABI wint_t __towlower(wint_t __c, __locale_t __loc) { return towlower_l(__c, __loc); }
140
141inline _LIBCPP_HIDE_FROM_ABI int __wcscoll(const wchar_t* __ws1, const wchar_t* __ws2, __locale_t __loc) {
142 return wcscoll_l(__ws1, __ws2, __loc);
143}
144
145inline _LIBCPP_HIDE_FROM_ABI size_t __wcsxfrm(wchar_t* __dest, const wchar_t* __src, size_t __n, __locale_t __loc) {
146 return wcsxfrm_l(__dest, __src, __n, __loc);
147}
148# endif // _LIBCPP_HAS_WIDE_CHARACTERS
149
150inline _LIBCPP_HIDE_FROM_ABI
151size_t __strftime(char* __s, size_t __max, const char* __format, const struct tm* __tm, __locale_t __loc) {
152 return strftime_l(__s, __max, __format, __tm, __loc);
153}
154
155//
156// Other functions
157//
158inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __mb_len_max(__locale_t __loc) {
159 __locale_guard __current(__loc);
160 return MB_CUR_MAX;
161}
162
163# if _LIBCPP_HAS_WIDE_CHARACTERS
164inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __c, __locale_t __loc) {
165 __locale_guard __current(__loc);
166 return std::btowc(__c);
167}
168
169inline _LIBCPP_HIDE_FROM_ABI int __wctob(wint_t __c, __locale_t __loc) {
170 __locale_guard __current(__loc);
171 return std::wctob(__c);
172}
173
174inline _LIBCPP_HIDE_FROM_ABI size_t
175__wcsnrtombs(char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, __locale_t __loc) {
176 __locale_guard __current(__loc);
177 return ::wcsnrtombs(__dest, __src, __nwc, __len, __ps); // non-standard
178}
179
180inline _LIBCPP_HIDE_FROM_ABI size_t __wcrtomb(char* __s, wchar_t __wc, mbstate_t* __ps, __locale_t __loc) {
181 __locale_guard __current(__loc);
182 return std::wcrtomb(__s, __wc, __ps);
183}
184
185inline _LIBCPP_HIDE_FROM_ABI size_t
186__mbsnrtowcs(wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, __locale_t __loc) {
187 __locale_guard __current(__loc);
188 return ::mbsnrtowcs(__dest, __src, __nms, __len, __ps); // non-standard
189}
190
191inline _LIBCPP_HIDE_FROM_ABI size_t
192__mbrtowc(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) {
193 __locale_guard __current(__loc);
194 return std::mbrtowc(__pwc, __s, __n, __ps);
195}
196
197inline _LIBCPP_HIDE_FROM_ABI int __mbtowc(wchar_t* __pwc, const char* __pmb, size_t __max, __locale_t __loc) {
198 __locale_guard __current(__loc);
199 return std::mbtowc(__pwc, __pmb, __max);
200}
201
202inline _LIBCPP_HIDE_FROM_ABI size_t __mbrlen(const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) {
203 __locale_guard __current(__loc);
204 return std::mbrlen(__s, __n, __ps);
205}
206
207inline _LIBCPP_HIDE_FROM_ABI size_t
208__mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, __locale_t __loc) {
209 __locale_guard __current(__loc);
210 return std::mbsrtowcs(__dest, __src, __len, __ps);
211}
212# endif // _LIBCPP_HAS_WIDE_CHARACTERS
213#endif // _LIBCPP_BUILDING_LIBRARY
214
215#ifndef _LIBCPP_COMPILER_GCC // GCC complains that this can't be always_inline due to C-style varargs
216_LIBCPP_HIDE_FROM_ABI
217#endif
218inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snprintf(
219 char* __s, size_t __n, __locale_t __loc, const char* __format, ...) {
220 va_list __va;
221 va_start(__va, __format);
222 __locale_guard __current(__loc);
223 int __res = std::vsnprintf(__s, __n, __format, __va);
224 va_end(__va);
225 return __res;
226}
227
228#ifndef _LIBCPP_COMPILER_GCC // GCC complains that this can't be always_inline due to C-style varargs
229_LIBCPP_HIDE_FROM_ABI
230#endif
231inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf(
232 char** __s, __locale_t __loc, const char* __format, ...) {
233 va_list __va;
234 va_start(__va, __format);
235 __locale_guard __current(__loc);
236 int __res = ::vasprintf(__s, __format, __va); // non-standard
237 va_end(__va);
238 return __res;
239}
240} // namespace __locale
241_LIBCPP_END_NAMESPACE_STD
242
243#endif // _LIBCPP___LOCALE_DIR_SUPPORT_NEWLIB_H
lib/libcxx/include/__locale_dir/support/no_locale/characters.h-4
......@@ -29,10 +29,6 @@ namespace __locale {
2929//
3030// Character manipulation functions
3131//
32inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t) { return std::isdigit(__c); }
33
34inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t) { return std::isxdigit(__c); }
35
3632#if defined(_LIBCPP_BUILDING_LIBRARY)
3733inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t) { return std::toupper(__c); }
3834
lib/libcxx/include/__locale_dir/support/no_locale/strtonum.h-9
......@@ -34,15 +34,6 @@ inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __
3434 return std::strtold(__nptr, __endptr);
3535}
3636
37inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t) {
38 return std::strtoll(__nptr, __endptr, __base);
39}
40
41inline _LIBCPP_HIDE_FROM_ABI unsigned long long
42__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t) {
43 return std::strtoull(__nptr, __endptr, __base);
44}
45
4637} // namespace __locale
4738_LIBCPP_END_NAMESPACE_STD
4839
lib/libcxx/include/__locale_dir/support/windows.h-29
......@@ -186,21 +186,9 @@ inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr
186186 return ::_strtod_l(__nptr, __endptr, __loc);
187187}
188188
189inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
190 return ::_strtoi64_l(__nptr, __endptr, __base, __loc);
191}
192inline _LIBCPP_HIDE_FROM_ABI unsigned long long
193__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
194 return ::_strtoui64_l(__nptr, __endptr, __base, __loc);
195}
196
197189//
198190// Character manipulation functions
199191//
200inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return _isdigit_l(__c, __loc); }
201
202inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return _isxdigit_l(__c, __loc); }
203
204192#if defined(_LIBCPP_BUILDING_LIBRARY)
205193inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return ::_toupper_l(__c, __loc); }
206194
......@@ -280,23 +268,6 @@ _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snpri
280268_LIBCPP_EXPORTED_FROM_ABI
281269_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf(char** __ret, __locale_t __loc, const char* __format, ...);
282270
283_LIBCPP_DIAGNOSTIC_PUSH
284_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgcc-compat")
285_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") // GCC doesn't support [[gnu::format]] on variadic templates
286#ifdef _LIBCPP_COMPILER_CLANG_BASED
287# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) _LIBCPP_ATTRIBUTE_FORMAT(__VA_ARGS__)
288#else
289# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) /* nothing */
290#endif
291
292template <class... _Args>
293_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
294 const char* __dest, __locale_t __loc, const char* __format, _Args&&... __args) {
295 return ::_sscanf_l(__dest, __format, __loc, std::forward<_Args>(__args)...);
296}
297_LIBCPP_DIAGNOSTIC_POP
298#undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
299
300271#if defined(_LIBCPP_BUILDING_LIBRARY)
301272struct __locale_guard {
302273 _LIBCPP_HIDE_FROM_ABI __locale_guard(__locale_t __l) : __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
lib/libcxx/include/__locale_dir/time.h+3-7
......@@ -601,17 +601,13 @@ private:
601601 template <> \
602602 _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \
603603 template <> \
604 _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
604 void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
605605 template <> \
606 _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze( \
607 char, const ctype<_CharT>&); \
606 __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
608607 extern template _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() \
609608 const; \
610609 extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*); \
611 extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \
612 extern template _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
613 extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type \
614 __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&);
610 extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&);
615611
616612_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char)
617613# if _LIBCPP_HAS_WIDE_CHARACTERS
lib/libcxx/include/__math/hypot.h+1-1
......@@ -53,7 +53,7 @@ inline _LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2> hypot(_A1 __x, _A2 __y) _NOEX
5353// Computes the three-dimensional hypotenuse: `std::hypot(x,y,z)`.
5454// The naive implementation might over-/underflow which is why this implementation is more involved:
5555// If the square of an argument might run into issues, we scale the arguments appropriately.
56// See https://github.com/llvm/llvm-project/issues/92782 for a detailed discussion and summary.
56// See https://llvm.org/PR92782 for a detailed discussion and summary.
5757template <class _Real>
5858_LIBCPP_HIDE_FROM_ABI _Real __hypot(_Real __x, _Real __y, _Real __z) {
5959 // Factors needed to determine if over-/underflow might happen
lib/libcxx/include/__math/logarithms.h+1-1
......@@ -58,7 +58,7 @@ inline _LIBCPP_HIDE_FROM_ABI double log10(_A1 __x) _NOEXCEPT {
5858inline _LIBCPP_HIDE_FROM_ABI int ilogb(float __x) _NOEXCEPT { return __builtin_ilogbf(__x); }
5959
6060template <class = int>
61_LIBCPP_HIDE_FROM_ABI double ilogb(double __x) _NOEXCEPT {
61_LIBCPP_HIDE_FROM_ABI int ilogb(double __x) _NOEXCEPT {
6262 return __builtin_ilogb(__x);
6363}
6464
lib/libcxx/include/__math/traits.h+80-11
......@@ -25,33 +25,26 @@ namespace __math {
2525
2626// signbit
2727
28// TODO(LLVM 22): Remove conditional once support for Clang 19 is dropped.
29#if defined(_LIBCPP_COMPILER_GCC) || __has_constexpr_builtin(__builtin_signbit)
30# define _LIBCPP_SIGNBIT_CONSTEXPR _LIBCPP_CONSTEXPR_SINCE_CXX23
31#else
32# define _LIBCPP_SIGNBIT_CONSTEXPR
33#endif
34
3528// The universal C runtime (UCRT) in the WinSDK provides floating point overloads
3629// for std::signbit(). By defining our overloads as templates, we can work around
3730// this issue as templates are less preferred than non-template functions.
3831template <class = void>
39[[__nodiscard__]] inline _LIBCPP_SIGNBIT_CONSTEXPR _LIBCPP_HIDE_FROM_ABI bool signbit(float __x) _NOEXCEPT {
32[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool signbit(float __x) _NOEXCEPT {
4033 return __builtin_signbit(__x);
4134}
4235
4336template <class = void>
44[[__nodiscard__]] inline _LIBCPP_SIGNBIT_CONSTEXPR _LIBCPP_HIDE_FROM_ABI bool signbit(double __x) _NOEXCEPT {
37[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool signbit(double __x) _NOEXCEPT {
4538 return __builtin_signbit(__x);
4639}
4740
4841template <class = void>
49[[__nodiscard__]] inline _LIBCPP_SIGNBIT_CONSTEXPR _LIBCPP_HIDE_FROM_ABI bool signbit(long double __x) _NOEXCEPT {
42[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool signbit(long double __x) _NOEXCEPT {
5043 return __builtin_signbit(__x);
5144}
5245
5346template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>
54[[__nodiscard__]] inline _LIBCPP_SIGNBIT_CONSTEXPR _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT {
47[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT {
5548 return __x < 0;
5649}
5750
......@@ -189,6 +182,82 @@ template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_ar
189182 return __builtin_isunordered((type)__x, (type)__y);
190183}
191184
185// MS UCRT incorrectly defines some functions in a way not working with integer types. Until C++20, this was worked
186// around by -fdelayed-template-parsing. Since C++20, we can use standard feature "requires" instead.
187
188// TODO: Remove the workaround once UCRT fixes these functions. Note that this doesn't seem planned as of 2025-07 per
189// https://developercommunity.visualstudio.com/t/10294165.
190
191#if defined(_LIBCPP_MSVCRT) && _LIBCPP_STD_VER >= 20
192namespace __ucrt {
193template <class _A1>
194 requires is_integral_v<_A1>
195[[nodiscard]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) noexcept {
196 return true;
197}
198
199template <class _A1>
200 requires is_integral_v<_A1>
201[[nodiscard]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1) noexcept {
202 return false;
203}
204
205template <class _A1>
206 requires is_integral_v<_A1>
207[[nodiscard]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) noexcept {
208 return false;
209}
210
211template <class _A1>
212 requires is_integral_v<_A1>
213[[nodiscard]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) noexcept {
214 return __x != 0;
215}
216
217template <class _A1, class _A2>
218 requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2>
219[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) noexcept {
220 using type = __promote_t<_A1, _A2>;
221 return __builtin_isgreater((type)__x, (type)__y);
222}
223
224template <class _A1, class _A2>
225 requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2>
226[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) noexcept {
227 using type = __promote_t<_A1, _A2>;
228 return __builtin_isgreaterequal((type)__x, (type)__y);
229}
230
231template <class _A1, class _A2>
232 requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2>
233[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) noexcept {
234 using type = __promote_t<_A1, _A2>;
235 return __builtin_isless((type)__x, (type)__y);
236}
237
238template <class _A1, class _A2>
239 requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2>
240[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) noexcept {
241 using type = __promote_t<_A1, _A2>;
242 return __builtin_islessequal((type)__x, (type)__y);
243}
244
245template <class _A1, class _A2>
246 requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2>
247[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) noexcept {
248 using type = __promote_t<_A1, _A2>;
249 return __builtin_islessgreater((type)__x, (type)__y);
250}
251
252template <class _A1, class _A2>
253 requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2>
254[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) noexcept {
255 using type = __promote_t<_A1, _A2>;
256 return __builtin_isunordered((type)__x, (type)__y);
257}
258} // namespace __ucrt
259#endif
260
192261} // namespace __math
193262
194263_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__mdspan/extents.h+7-4
......@@ -25,6 +25,7 @@
2525#include <__type_traits/integer_traits.h>
2626#include <__type_traits/is_convertible.h>
2727#include <__type_traits/is_nothrow_constructible.h>
28#include <__type_traits/is_signed.h>
2829#include <__type_traits/make_unsigned.h>
2930#include <__utility/integer_sequence.h>
3031#include <__utility/unreachable.h>
......@@ -298,11 +299,13 @@ private:
298299
299300public:
300301 // [mdspan.extents.obs], observers of multidimensional index space
301 _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return __rank_; }
302 _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return __rank_dynamic_; }
302 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return __rank_; }
303 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return __rank_dynamic_; }
303304
304 _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept { return __vals_.__value(__r); }
305 _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept {
305 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept {
306 return __vals_.__value(__r);
307 }
308 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept {
306309 return _Values::__static_value(__r);
307310 }
308311
lib/libcxx/include/__mdspan/layout_stride.h+4-5
......@@ -272,11 +272,10 @@ public:
272272 return [&]<size_t... _Pos>(index_sequence<_Pos...>) {
273273 if ((__extents_.extent(_Pos) * ... * 1) == 0)
274274 return static_cast<index_type>(0);
275 else
276 return static_cast<index_type>(
277 static_cast<index_type>(1) +
278 (((__extents_.extent(_Pos) - static_cast<index_type>(1)) * __strides_[_Pos]) + ... +
279 static_cast<index_type>(0)));
275
276 return static_cast<index_type>(
277 static_cast<index_type>(1) + (((__extents_.extent(_Pos) - static_cast<index_type>(1)) * __strides_[_Pos]) +
278 ... + static_cast<index_type>(0)));
280279 }(make_index_sequence<__rank_>());
281280 }
282281 }
lib/libcxx/include/__mdspan/mdspan.h+29-23
......@@ -87,16 +87,17 @@ public:
8787 using data_handle_type = typename accessor_type::data_handle_type;
8888 using reference = typename accessor_type::reference;
8989
90 _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return extents_type::rank(); }
91 _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
92 _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept {
90 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return extents_type::rank(); }
91 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept {
92 return extents_type::rank_dynamic();
93 }
94 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept {
9395 return extents_type::static_extent(__r);
9496 }
95 _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept {
97 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept {
9698 return __map_.extents().extent(__r);
97 };
99 }
98100
99public:
100101 //--------------------------------------------------------------------------------
101102 // [mdspan.mdspan.cons], mdspan constructors, assignment, and destructor
102103
......@@ -185,7 +186,7 @@ public:
185186 requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) &&
186187 (is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) &&
187188 (sizeof...(_OtherIndexTypes) == rank()))
188 _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](_OtherIndexTypes... __indices) const {
189 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](_OtherIndexTypes... __indices) const {
189190 // Note the standard layouts would also check this, but user provided ones may not, so we
190191 // check the precondition here
191192 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__is_multidimensional_index_in(extents(), __indices...),
......@@ -196,7 +197,8 @@ public:
196197 template <class _OtherIndexType>
197198 requires(is_convertible_v<const _OtherIndexType&, index_type> &&
198199 is_nothrow_constructible_v<index_type, const _OtherIndexType&>)
199 _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](const array< _OtherIndexType, rank()>& __indices) const {
200 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference
201 operator[](const array< _OtherIndexType, rank()>& __indices) const {
200202 return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
201203 return __map_(__indices[_Idxs]...);
202204 }(make_index_sequence<rank()>()));
......@@ -205,13 +207,13 @@ public:
205207 template <class _OtherIndexType>
206208 requires(is_convertible_v<const _OtherIndexType&, index_type> &&
207209 is_nothrow_constructible_v<index_type, const _OtherIndexType&>)
208 _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](span<_OtherIndexType, rank()> __indices) const {
210 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](span<_OtherIndexType, rank()> __indices) const {
209211 return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
210212 return __map_(__indices[_Idxs]...);
211213 }(make_index_sequence<rank()>()));
212214 }
213215
214 _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept {
216 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept {
215217 // Could leave this as only checked in debug mode: semantically size() is never
216218 // guaranteed to be related to any accessible range
217219 _LIBCPP_ASSERT_UNCATEGORIZED(
......@@ -237,24 +239,28 @@ public:
237239 swap(__x.__acc_, __y.__acc_);
238240 }
239241
240 _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { return __map_.extents(); };
241 _LIBCPP_HIDE_FROM_ABI constexpr const data_handle_type& data_handle() const noexcept { return __ptr_; };
242 _LIBCPP_HIDE_FROM_ABI constexpr const mapping_type& mapping() const noexcept { return __map_; };
243 _LIBCPP_HIDE_FROM_ABI constexpr const accessor_type& accessor() const noexcept { return __acc_; };
242 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept {
243 return __map_.extents();
244 }
245 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const data_handle_type& data_handle() const noexcept { return __ptr_; }
246 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const mapping_type& mapping() const noexcept { return __map_; }
247 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const accessor_type& accessor() const noexcept { return __acc_; }
244248
245249 // per LWG-4021 "mdspan::is_always_meow() should be noexcept"
246 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept { return mapping_type::is_always_unique(); };
247 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept {
250 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept {
251 return mapping_type::is_always_unique();
252 }
253 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept {
248254 return mapping_type::is_always_exhaustive();
249 };
250 _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept {
255 }
256 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept {
251257 return mapping_type::is_always_strided();
252 };
258 }
253259
254 _LIBCPP_HIDE_FROM_ABI constexpr bool is_unique() const { return __map_.is_unique(); };
255 _LIBCPP_HIDE_FROM_ABI constexpr bool is_exhaustive() const { return __map_.is_exhaustive(); };
256 _LIBCPP_HIDE_FROM_ABI constexpr bool is_strided() const { return __map_.is_strided(); };
257 _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const { return __map_.stride(__r); };
260 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool is_unique() const { return __map_.is_unique(); }
261 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool is_exhaustive() const { return __map_.is_exhaustive(); }
262 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool is_strided() const { return __map_.is_strided(); }
263 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const { return __map_.stride(__r); }
258264
259265private:
260266 _LIBCPP_NO_UNIQUE_ADDRESS data_handle_type __ptr_{};
lib/libcxx/include/__memory/addressof.h+7-5
......@@ -19,7 +19,8 @@
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
2121template <class _Tp>
22inline _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_NO_CFI _LIBCPP_HIDE_FROM_ABI _Tp* addressof(_Tp& __x) _NOEXCEPT {
22[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_NO_CFI _LIBCPP_HIDE_FROM_ABI _Tp*
23addressof(_Tp& __x) _NOEXCEPT {
2324 return __builtin_addressof(__x);
2425}
2526
......@@ -27,24 +28,25 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_NO_CFI _LIBCPP_HIDE_FROM_ABI _Tp* a
2728// Objective-C++ Automatic Reference Counting uses qualified pointers
2829// that require special addressof() signatures.
2930template <class _Tp>
30inline _LIBCPP_HIDE_FROM_ABI __strong _Tp* addressof(__strong _Tp& __x) _NOEXCEPT {
31[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __strong _Tp* addressof(__strong _Tp& __x) _NOEXCEPT {
3132 return &__x;
3233}
3334
3435# if __has_feature(objc_arc_weak)
3536template <class _Tp>
36inline _LIBCPP_HIDE_FROM_ABI __weak _Tp* addressof(__weak _Tp& __x) _NOEXCEPT {
37[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __weak _Tp* addressof(__weak _Tp& __x) _NOEXCEPT {
3738 return &__x;
3839}
3940# endif
4041
4142template <class _Tp>
42inline _LIBCPP_HIDE_FROM_ABI __autoreleasing _Tp* addressof(__autoreleasing _Tp& __x) _NOEXCEPT {
43[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __autoreleasing _Tp* addressof(__autoreleasing _Tp& __x) _NOEXCEPT {
4344 return &__x;
4445}
4546
4647template <class _Tp>
47inline _LIBCPP_HIDE_FROM_ABI __unsafe_unretained _Tp* addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT {
48[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __unsafe_unretained _Tp*
49addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT {
4850 return &__x;
4951}
5052#endif
lib/libcxx/include/__memory/align.h+18-1
......@@ -11,6 +11,7 @@
1111
1212#include <__config>
1313#include <__cstddef/size_t.h>
14#include <cstdint>
1415
1516#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1617# pragma GCC system_header
......@@ -18,7 +19,23 @@
1819
1920_LIBCPP_BEGIN_NAMESPACE_STD
2021
21_LIBCPP_EXPORTED_FROM_ABI void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
22inline namespace __align_inline {
23_LIBCPP_HIDE_FROM_ABI inline void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space) {
24 void* __r = nullptr;
25 if (__sz <= __space) {
26 char* __p1 = static_cast<char*>(__ptr);
27 char* __p2 = reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(__p1 + (__align - 1)) & -__align);
28 size_t __d = static_cast<size_t>(__p2 - __p1);
29 if (__d <= __space - __sz) {
30 __r = __p2;
31 __ptr = __r;
32 __space -= __d;
33 }
34 }
35 return __r;
36}
37
38} // namespace __align_inline
2239
2340_LIBCPP_END_NAMESPACE_STD
2441
lib/libcxx/include/__memory/allocate_at_least.h+15-10
......@@ -19,26 +19,31 @@
1919
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
22template <class _Pointer, class _SizeT = size_t>
23struct __allocation_result {
24 _Pointer ptr;
25 _SizeT count;
26
27 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __allocation_result(_Pointer __ptr, _SizeT __count)
28 : ptr(__ptr), count(__count) {}
29};
30_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__allocation_result);
31
2232#if _LIBCPP_STD_VER >= 23
2333
2434template <class _Alloc>
2535[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto __allocate_at_least(_Alloc& __alloc, size_t __n) {
26 return std::allocator_traits<_Alloc>::allocate_at_least(__alloc, __n);
36 auto __res = std::allocator_traits<_Alloc>::allocate_at_least(__alloc, __n);
37 return __allocation_result{__res.ptr, __res.count};
2738}
2839
2940#else
3041
31template <class _Pointer>
32struct __allocation_result {
33 _Pointer ptr;
34 size_t count;
35};
36
37template <class _Alloc>
42template <class _Alloc, class _Traits = allocator_traits<_Alloc> >
3843[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
39_LIBCPP_CONSTEXPR __allocation_result<typename allocator_traits<_Alloc>::pointer>
44_LIBCPP_CONSTEXPR __allocation_result<typename _Traits::pointer, typename _Traits::size_type>
4045__allocate_at_least(_Alloc& __alloc, size_t __n) {
41 return {__alloc.allocate(__n), __n};
46 return __allocation_result<typename _Traits::pointer, typename _Traits::size_type>(__alloc.allocate(__n), __n);
4247}
4348
4449#endif // _LIBCPP_STD_VER >= 23
lib/libcxx/include/__memory/allocator.h+14-26
......@@ -14,7 +14,6 @@
1414#include <__cstddef/ptrdiff_t.h>
1515#include <__cstddef/size_t.h>
1616#include <__memory/addressof.h>
17#include <__memory/allocate_at_least.h>
1817#include <__memory/allocator_traits.h>
1918#include <__new/allocate.h>
2019#include <__new/exceptions.h>
......@@ -51,33 +50,21 @@ public:
5150};
5251#endif // _LIBCPP_STD_VER <= 17
5352
54// This class provides a non-trivial default constructor to the class that derives from it
55// if the condition is satisfied.
56//
57// The second template parameter exists to allow giving a unique type to __non_trivial_if,
58// which makes it possible to avoid breaking the ABI when making this a base class of an
59// existing class. Without that, imagine we have classes D1 and D2, both of which used to
60// have no base classes, but which now derive from __non_trivial_if. The layout of a class
61// that inherits from both D1 and D2 will change because the two __non_trivial_if base
62// classes are not allowed to share the same address.
63//
64// By making those __non_trivial_if base classes unique, we work around this problem and
65// it is safe to start deriving from __non_trivial_if in existing classes.
66template <bool _Cond, class _Unique>
67struct __non_trivial_if {};
53template <bool, class _Unique>
54struct __non_trivially_default_constructible_if {};
6855
6956template <class _Unique>
70struct __non_trivial_if<true, _Unique> {
71 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __non_trivial_if() _NOEXCEPT {}
57struct __non_trivially_default_constructible_if<true, _Unique> {
58 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __non_trivially_default_constructible_if() {}
7259};
7360
74// allocator
75//
76// Note: For ABI compatibility between C++20 and previous standards, we make
77// allocator<void> trivial in C++20.
78
7961template <class _Tp>
80class allocator : private __non_trivial_if<!is_void<_Tp>::value, allocator<_Tp> > {
62class allocator
63// TODO(LLVM 24): Remove the opt-out
64#ifdef _LIBCPP_DEPRECATED_ABI_NON_TRIVIAL_ALLOCATOR
65 : __non_trivially_default_constructible_if<!is_void<_Tp>::value, allocator<_Tp> >
66#endif
67{
8168 static_assert(!is_const<_Tp>::value, "std::allocator does not support const types");
8269 static_assert(!is_volatile<_Tp>::value, "std::allocator does not support volatile types");
8370
......@@ -133,10 +120,11 @@ public:
133120 typedef allocator<_Up> other;
134121 };
135122
136 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI pointer address(reference __x) const _NOEXCEPT {
123 [[__nodiscard__]] _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI pointer address(reference __x) const _NOEXCEPT {
137124 return std::addressof(__x);
138125 }
139 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI const_pointer address(const_reference __x) const _NOEXCEPT {
126 [[__nodiscard__]] _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI const_pointer
127 address(const_reference __x) const _NOEXCEPT {
140128 return std::addressof(__x);
141129 }
142130
......@@ -144,7 +132,7 @@ public:
144132 return allocate(__n);
145133 }
146134
147 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
135 [[__nodiscard__]] _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
148136 return size_type(~0) / sizeof(_Tp);
149137 }
150138
lib/libcxx/include/__memory/allocator_traits.h+6-4
......@@ -314,23 +314,25 @@ struct allocator_traits {
314314 }
315315
316316 template <class _Ap = _Alloc, __enable_if_t<__has_max_size_v<const _Ap>, int> = 0>
317 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static size_type max_size(const allocator_type& __a) _NOEXCEPT {
317 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static size_type
318 max_size(const allocator_type& __a) _NOEXCEPT {
318319 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
319320 return __a.max_size();
320321 _LIBCPP_SUPPRESS_DEPRECATED_POP
321322 }
322323 template <class _Ap = _Alloc, __enable_if_t<!__has_max_size_v<const _Ap>, int> = 0>
323 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static size_type max_size(const allocator_type&) _NOEXCEPT {
324 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static size_type
325 max_size(const allocator_type&) _NOEXCEPT {
324326 return numeric_limits<size_type>::max() / sizeof(value_type);
325327 }
326328
327329 template <class _Ap = _Alloc, __enable_if_t<__has_select_on_container_copy_construction_v<const _Ap>, int> = 0>
328 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static allocator_type
330 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static allocator_type
329331 select_on_container_copy_construction(const allocator_type& __a) {
330332 return __a.select_on_container_copy_construction();
331333 }
332334 template <class _Ap = _Alloc, __enable_if_t<!__has_select_on_container_copy_construction_v<const _Ap>, int> = 0>
333 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static allocator_type
335 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static allocator_type
334336 select_on_container_copy_construction(const allocator_type& __a) {
335337 return __a;
336338 }
lib/libcxx/include/__memory/compressed_pair.h+15-9
......@@ -28,8 +28,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2828// understand how it works). //
2929// ================================================================================================================== //
3030
31// The first member is aligned to the alignment of the second member to force padding in front of the compressed pair
32// in case there are members before it.
31// On GCC, the first member is aligned to the alignment of the second member to force padding in front of the compressed
32// pair in case there are members before it.
3333//
3434// For example:
3535// (assuming x86-64 linux)
......@@ -52,7 +52,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
5252//
5353// Furthermore, that alignment must be the same as what was used in the old __compressed_pair layout, so we must
5454// handle reference types specially since alignof(T&) == alignof(T).
55// See https://github.com/llvm/llvm-project/issues/118559.
55// See https://llvm.org/PR118559.
56//
57// On Clang, this is unnecessary, since we use anonymous structs instead, which automatically handle the alignment
58// correctly.
5659
5760#ifndef _LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING
5861
......@@ -64,7 +67,7 @@ inline const size_t __compressed_pair_alignment<_Tp&> = _LIBCPP_ALIGNOF(void*);
6467
6568template <class _ToPad>
6669inline const bool __is_reference_or_unpadded_object =
67 (is_empty<_ToPad>::value && !__libcpp_is_final<_ToPad>::value) || sizeof(_ToPad) == __datasizeof_v<_ToPad>;
70 (is_empty<_ToPad>::value && !__is_final_v<_ToPad>) || sizeof(_ToPad) == __datasizeof_v<_ToPad>;
6871
6972template <class _Tp>
7073inline const bool __is_reference_or_unpadded_object<_Tp&> = true;
......@@ -80,6 +83,10 @@ class __compressed_pair_padding {
8083template <class _ToPad>
8184class __compressed_pair_padding<_ToPad, true> {};
8285
86# define _LIBCPP_COMPRESSED_ELEMENT(T1, Initializer1) \
87 _LIBCPP_NO_UNIQUE_ADDRESS T1 Initializer1; \
88 _LIBCPP_NO_UNIQUE_ADDRESS ::std::__compressed_pair_padding<T1> _LIBCPP_CONCAT3(__padding_, __LINE__, _)
89
8390// TODO: Fix the ABI for GCC as well once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121637 is fixed
8491# ifdef _LIBCPP_COMPILER_GCC
8592# define _LIBCPP_COMPRESSED_PAIR(T1, Initializer1, T2, Initializer2) \
......@@ -100,8 +107,7 @@ class __compressed_pair_padding<_ToPad, true> {};
100107# else
101108# define _LIBCPP_COMPRESSED_PAIR(T1, Initializer1, T2, Initializer2) \
102109 struct { \
103 _LIBCPP_NO_UNIQUE_ADDRESS \
104 __attribute__((__aligned__(::std::__compressed_pair_alignment<T2>))) T1 Initializer1; \
110 _LIBCPP_NO_UNIQUE_ADDRESS T1 Initializer1; \
105111 _LIBCPP_NO_UNIQUE_ADDRESS ::std::__compressed_pair_padding<T1> _LIBCPP_CONCAT3(__padding1_, __LINE__, _); \
106112 _LIBCPP_NO_UNIQUE_ADDRESS T2 Initializer2; \
107113 _LIBCPP_NO_UNIQUE_ADDRESS ::std::__compressed_pair_padding<T2> _LIBCPP_CONCAT3(__padding2_, __LINE__, _); \
......@@ -109,9 +115,7 @@ class __compressed_pair_padding<_ToPad, true> {};
109115
110116# define _LIBCPP_COMPRESSED_TRIPLE(T1, Initializer1, T2, Initializer2, T3, Initializer3) \
111117 struct { \
112 _LIBCPP_NO_UNIQUE_ADDRESS \
113 __attribute__((__aligned__(::std::__compressed_pair_alignment<T2>), \
114 __aligned__(::std::__compressed_pair_alignment<T3>))) T1 Initializer1; \
118 _LIBCPP_NO_UNIQUE_ADDRESS T1 Initializer1; \
115119 _LIBCPP_NO_UNIQUE_ADDRESS ::std::__compressed_pair_padding<T1> _LIBCPP_CONCAT3(__padding1_, __LINE__, _); \
116120 _LIBCPP_NO_UNIQUE_ADDRESS T2 Initializer2; \
117121 _LIBCPP_NO_UNIQUE_ADDRESS ::std::__compressed_pair_padding<T2> _LIBCPP_CONCAT3(__padding2_, __LINE__, _); \
......@@ -121,6 +125,8 @@ class __compressed_pair_padding<_ToPad, true> {};
121125# endif
122126
123127#else
128# define _LIBCPP_COMPRESSED_ELEMENT(T1, Initializer1) _LIBCPP_NO_UNIQUE_ADDRESS T1 Initializer1
129
124130# define _LIBCPP_COMPRESSED_PAIR(T1, Name1, T2, Name2) \
125131 _LIBCPP_NO_UNIQUE_ADDRESS T1 Name1; \
126132 _LIBCPP_NO_UNIQUE_ADDRESS T2 Name2
lib/libcxx/include/__memory/construct_at.h+12-23
......@@ -14,7 +14,6 @@
1414#include <__config>
1515#include <__memory/addressof.h>
1616#include <__new/placement_new_delete.h>
17#include <__type_traits/enable_if.h>
1817#include <__type_traits/is_array.h>
1918#include <__utility/declval.h>
2019#include <__utility/forward.h>
......@@ -33,7 +32,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3332#if _LIBCPP_STD_VER >= 20
3433
3534template <class _Tp, class... _Args, class = decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))>
36_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&&... __args) {
35_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* _LIBCPP_DIAGNOSE_NULLPTR __location, _Args&&... __args) {
3736 _LIBCPP_ASSERT_NON_NULL(__location != nullptr, "null pointer given to construct_at");
3837 return ::new (static_cast<void*>(__location)) _Tp(std::forward<_Args>(__args)...);
3938}
......@@ -55,35 +54,25 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp* __construct_at(_Tp* __l
5554// The internal functions are available regardless of the language version (with the exception of the `__destroy_at`
5655// taking an array).
5756
58template <class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
57template <class _Tp>
5958_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy_at(_Tp* __loc) {
6059 _LIBCPP_ASSERT_NON_NULL(__loc != nullptr, "null pointer given to destroy_at");
61 __loc->~_Tp();
62}
63
6460#if _LIBCPP_STD_VER >= 20
65template <class _Tp, __enable_if_t<is_array<_Tp>::value, int> = 0>
66_LIBCPP_HIDE_FROM_ABI constexpr void __destroy_at(_Tp* __loc) {
67 _LIBCPP_ASSERT_NON_NULL(__loc != nullptr, "null pointer given to destroy_at");
68 for (auto&& __val : *__loc)
69 std::__destroy_at(std::addressof(__val));
70}
61 if constexpr (is_array_v<_Tp>) {
62 for (auto&& __val : *__loc)
63 std::__destroy_at(std::addressof(__val));
64 } else
7165#endif
72
73#if _LIBCPP_STD_VER >= 17
74
75template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
76_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void destroy_at(_Tp* __loc) {
77 std::__destroy_at(__loc);
66 {
67 __loc->~_Tp();
68 }
7869}
7970
80# if _LIBCPP_STD_VER >= 20
81template <class _Tp, enable_if_t<is_array_v<_Tp>, int> = 0>
82_LIBCPP_HIDE_FROM_ABI constexpr void destroy_at(_Tp* __loc) {
71#if _LIBCPP_STD_VER >= 17
72template <class _Tp>
73_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void destroy_at(_Tp* _LIBCPP_DIAGNOSE_NULLPTR __loc) {
8374 std::__destroy_at(__loc);
8475}
85# endif
86
8776#endif // _LIBCPP_STD_VER >= 17
8877
8978_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__memory/inout_ptr.h+1-1
......@@ -96,7 +96,7 @@ private:
9696};
9797
9898template <class _Pointer = void, class _Smart, class... _Args>
99_LIBCPP_HIDE_FROM_ABI auto inout_ptr(_Smart& __s, _Args&&... __args) {
99[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto inout_ptr(_Smart& __s, _Args&&... __args) {
100100 using _Ptr = conditional_t<is_void_v<_Pointer>, __pointer_of_t<_Smart>, _Pointer>;
101101 return std::inout_ptr_t<_Smart, _Ptr, _Args&&...>(__s, std::forward<_Args>(__args)...);
102102}
lib/libcxx/include/__memory/is_sufficiently_aligned.h+1-1
......@@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2323#if _LIBCPP_STD_VER >= 26
2424
2525template <size_t _Alignment, class _Tp>
26_LIBCPP_HIDE_FROM_ABI bool is_sufficiently_aligned(_Tp* __ptr) {
26[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_sufficiently_aligned(_Tp* __ptr) {
2727 return reinterpret_cast<uintptr_t>(__ptr) % _Alignment == 0;
2828}
2929
lib/libcxx/include/__memory/out_ptr.h+1-1
......@@ -88,7 +88,7 @@ private:
8888};
8989
9090template <class _Pointer = void, class _Smart, class... _Args>
91_LIBCPP_HIDE_FROM_ABI auto out_ptr(_Smart& __s, _Args&&... __args) {
91[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto out_ptr(_Smart& __s, _Args&&... __args) {
9292 using _Ptr = conditional_t<is_void_v<_Pointer>, __pointer_of_t<_Smart>, _Pointer>;
9393 return std::out_ptr_t<_Smart, _Ptr, _Args&&...>(__s, std::forward<_Args>(__args)...);
9494}
lib/libcxx/include/__memory/pointer_traits.h+1-1
......@@ -255,7 +255,7 @@ concept __resettable_smart_pointer_with_args = requires(_Smart __s, _Pointer __p
255255// This function ensures safe conversions between fancy pointers at compile-time, where we avoid casts from/to
256256// `__void_pointer` by obtaining the underlying raw pointer from the fancy pointer using `std::to_address`,
257257// then dereferencing it to retrieve the pointed-to object, and finally constructing the target fancy pointer
258// to that object using the `std::pointer_traits<>::pinter_to` function.
258// to that object using the `std::pointer_traits<>::pointer_to` function.
259259template <class _PtrTo, class _PtrFrom>
260260_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _PtrTo __static_fancy_pointer_cast(const _PtrFrom& __p) {
261261 using __ptr_traits = pointer_traits<_PtrTo>;
lib/libcxx/include/__memory/raw_storage_iterator.h+3-9
......@@ -28,15 +28,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2828
2929#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR)
3030
31_LIBCPP_SUPPRESS_DEPRECATED_PUSH
3231template <class _OutputIterator, class _Tp>
3332class _LIBCPP_DEPRECATED_IN_CXX17 raw_storage_iterator
34# if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
35 : public iterator<output_iterator_tag, void, void, void, void>
36# endif
37{
38 _LIBCPP_SUPPRESS_DEPRECATED_POP
39
33 : public __iterator_base<raw_storage_iterator<_OutputIterator, _Tp>, output_iterator_tag, void, void, void, void> {
4034private:
4135 _OutputIterator __x_;
4236
......@@ -52,7 +46,7 @@ public:
5246 typedef void reference;
5347
5448 _LIBCPP_HIDE_FROM_ABI explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {}
55 _LIBCPP_HIDE_FROM_ABI raw_storage_iterator& operator*() { return *this; }
49 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI raw_storage_iterator& operator*() { return *this; }
5650 _LIBCPP_HIDE_FROM_ABI raw_storage_iterator& operator=(const _Tp& __element) {
5751 ::new ((void*)std::addressof(*__x_)) _Tp(__element);
5852 return *this;
......@@ -73,7 +67,7 @@ public:
7367 return __t;
7468 }
7569# if _LIBCPP_STD_VER >= 14
76 _LIBCPP_HIDE_FROM_ABI _OutputIterator base() const { return __x_; }
70 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _OutputIterator base() const { return __x_; }
7771# endif
7872};
7973
lib/libcxx/include/__memory/shared_count.h+9-30
......@@ -22,37 +22,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
2323// should be sufficient for thread safety.
2424// See https://llvm.org/PR22803
25#if (defined(__clang__) && __has_builtin(__atomic_add_fetch) && defined(__ATOMIC_RELAXED) && \
26 defined(__ATOMIC_ACQ_REL)) || \
27 defined(_LIBCPP_COMPILER_GCC)
28# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT 1
29#else
30# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT 0
31#endif
32
33template <class _ValueType>
34inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_relaxed_load(_ValueType const* __value) {
35#if _LIBCPP_HAS_THREADS && defined(__ATOMIC_RELAXED) && \
36 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
37 return __atomic_load_n(__value, __ATOMIC_RELAXED);
38#else
39 return *__value;
40#endif
41}
42
43template <class _ValueType>
44inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_acquire_load(_ValueType const* __value) {
45#if _LIBCPP_HAS_THREADS && defined(__ATOMIC_ACQUIRE) && \
46 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
47 return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
48#else
49 return *__value;
50#endif
51}
5225
5326template <class _Tp>
5427inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT {
55#if _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT && _LIBCPP_HAS_THREADS
28#if _LIBCPP_HAS_THREADS
5629 return __atomic_add_fetch(std::addressof(__t), 1, __ATOMIC_RELAXED);
5730#else
5831 return __t += 1;
......@@ -61,7 +34,7 @@ inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_increment(_Tp& __t) _N
6134
6235template <class _Tp>
6336inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT {
64#if _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT && _LIBCPP_HAS_THREADS
37#if _LIBCPP_HAS_THREADS
6538 return __atomic_add_fetch(std::addressof(__t), -1, __ATOMIC_ACQ_REL);
6639#else
6740 return __t -= 1;
......@@ -95,7 +68,13 @@ public:
9568 return false;
9669 }
9770#endif
98 _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __libcpp_relaxed_load(&__shared_owners_) + 1; }
71 _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT {
72#if _LIBCPP_HAS_THREADS
73 return __atomic_load_n(&__shared_owners_, __ATOMIC_RELAXED) + 1;
74#else
75 return __shared_owners_ + 1;
76#endif
77 }
9978};
10079
10180class _LIBCPP_EXPORTED_FROM_ABI __shared_weak_count : private __shared_count {
lib/libcxx/include/__memory/shared_ptr.h+100-145
......@@ -41,19 +41,18 @@
4141#include <__type_traits/enable_if.h>
4242#include <__type_traits/integral_constant.h>
4343#include <__type_traits/is_array.h>
44#include <__type_traits/is_bounded_array.h>
4544#include <__type_traits/is_constructible.h>
4645#include <__type_traits/is_convertible.h>
4746#include <__type_traits/is_function.h>
4847#include <__type_traits/is_reference.h>
4948#include <__type_traits/is_same.h>
50#include <__type_traits/is_unbounded_array.h>
5149#include <__type_traits/nat.h>
5250#include <__type_traits/negation.h>
5351#include <__type_traits/remove_cv.h>
5452#include <__type_traits/remove_extent.h>
5553#include <__type_traits/remove_reference.h>
5654#include <__utility/declval.h>
55#include <__utility/exception_guard.h>
5756#include <__utility/forward.h>
5857#include <__utility/move.h>
5958#include <__utility/swap.h>
......@@ -78,7 +77,7 @@ public:
7877 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
7978 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr& operator=(const bad_weak_ptr&) _NOEXCEPT = default;
8079 ~bad_weak_ptr() _NOEXCEPT override;
81 const char* what() const _NOEXCEPT override;
80 [[__nodiscard__]] const char* what() const _NOEXCEPT override;
8281};
8382
8483[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_weak_ptr() {
......@@ -316,10 +315,8 @@ public:
316315#endif
317316
318317 // A shared_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
319 // any bookkeeping, so it's always trivially relocatable. It is also replaceable because assignment just rebinds the
320 // shared_ptr to manage a different object.
318 // any bookkeeping, so it's always trivially relocatable.
321319 using __trivially_relocatable _LIBCPP_NODEBUG = shared_ptr;
322 using __replaceable _LIBCPP_NODEBUG = shared_ptr;
323320
324321private:
325322 element_type* __ptr_;
......@@ -352,23 +349,16 @@ public:
352349
353350 template <class _Yp, class _Dp, __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value, int> = 0>
354351 _LIBCPP_HIDE_FROM_ABI shared_ptr(_Yp* __p, _Dp __d) : __ptr_(__p) {
355#if _LIBCPP_HAS_EXCEPTIONS
356 try {
357#endif // _LIBCPP_HAS_EXCEPTIONS
358 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
359 typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT> _CntrlBlk;
352 auto __guard = std::__make_exception_guard([&] { __d(__p); });
353 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
354 typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT> _CntrlBlk;
360355#ifndef _LIBCPP_CXX03_LANG
361 __cntrl_ = new _CntrlBlk(__p, std::move(__d), _AllocT());
356 __cntrl_ = new _CntrlBlk(__p, std::move(__d), _AllocT());
362357#else
363358 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
364359#endif // not _LIBCPP_CXX03_LANG
365 __enable_weak_this(__p, __p);
366#if _LIBCPP_HAS_EXCEPTIONS
367 } catch (...) {
368 __d(__p);
369 throw;
370 }
371#endif // _LIBCPP_HAS_EXCEPTIONS
360 __enable_weak_this(__p, __p);
361 __guard.__complete();
372362 }
373363
374364 template <class _Yp,
......@@ -376,28 +366,21 @@ public:
376366 class _Alloc,
377367 __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value, int> = 0>
378368 _LIBCPP_HIDE_FROM_ABI shared_ptr(_Yp* __p, _Dp __d, _Alloc __a) : __ptr_(__p) {
379#if _LIBCPP_HAS_EXCEPTIONS
380 try {
381#endif // _LIBCPP_HAS_EXCEPTIONS
382 typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
383 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
384 typedef __allocator_destructor<_A2> _D2;
385 _A2 __a2(__a);
386 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
387 ::new ((void*)std::addressof(*__hold2.get()))
369 auto __guard = std::__make_exception_guard([&] { __d(__p); });
370 typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
371 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
372 typedef __allocator_destructor<_A2> _D2;
373 _A2 __a2(__a);
374 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
375 ::new ((void*)std::addressof(*__hold2.get()))
388376#ifndef _LIBCPP_CXX03_LANG
389 _CntrlBlk(__p, std::move(__d), __a);
377 _CntrlBlk(__p, std::move(__d), __a);
390378#else
391379 _CntrlBlk(__p, __d, __a);
392380#endif // not _LIBCPP_CXX03_LANG
393 __cntrl_ = std::addressof(*__hold2.release());
394 __enable_weak_this(__p, __p);
395#if _LIBCPP_HAS_EXCEPTIONS
396 } catch (...) {
397 __d(__p);
398 throw;
399 }
400#endif // _LIBCPP_HAS_EXCEPTIONS
381 __cntrl_ = std::addressof(*__hold2.release());
382 __enable_weak_this(__p, __p);
383 __guard.__complete();
401384 }
402385
403386 template <class _Dp>
......@@ -406,22 +389,15 @@ public:
406389 _Dp __d,
407390 __enable_if_t<__shared_ptr_nullptr_deleter_ctor_reqs<_Dp>::value, __nullptr_sfinae_tag> = __nullptr_sfinae_tag())
408391 : __ptr_(nullptr) {
409#if _LIBCPP_HAS_EXCEPTIONS
410 try {
411#endif // _LIBCPP_HAS_EXCEPTIONS
412 typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
413 typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT> _CntrlBlk;
392 auto __guard = std::__make_exception_guard([&] { __d(__p); });
393 typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
394 typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT> _CntrlBlk;
414395#ifndef _LIBCPP_CXX03_LANG
415 __cntrl_ = new _CntrlBlk(__p, std::move(__d), _AllocT());
396 __cntrl_ = new _CntrlBlk(__p, std::move(__d), _AllocT());
416397#else
417398 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
418399#endif // not _LIBCPP_CXX03_LANG
419#if _LIBCPP_HAS_EXCEPTIONS
420 } catch (...) {
421 __d(__p);
422 throw;
423 }
424#endif // _LIBCPP_HAS_EXCEPTIONS
400 __guard.__complete();
425401 }
426402
427403 template <class _Dp, class _Alloc>
......@@ -431,27 +407,20 @@ public:
431407 _Alloc __a,
432408 __enable_if_t<__shared_ptr_nullptr_deleter_ctor_reqs<_Dp>::value, __nullptr_sfinae_tag> = __nullptr_sfinae_tag())
433409 : __ptr_(nullptr) {
434#if _LIBCPP_HAS_EXCEPTIONS
435 try {
436#endif // _LIBCPP_HAS_EXCEPTIONS
437 typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
438 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
439 typedef __allocator_destructor<_A2> _D2;
440 _A2 __a2(__a);
441 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
442 ::new ((void*)std::addressof(*__hold2.get()))
410 auto __guard = std::__make_exception_guard([&] { __d(__p); });
411 typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
412 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
413 typedef __allocator_destructor<_A2> _D2;
414 _A2 __a2(__a);
415 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
416 ::new ((void*)std::addressof(*__hold2.get()))
443417#ifndef _LIBCPP_CXX03_LANG
444 _CntrlBlk(__p, std::move(__d), __a);
418 _CntrlBlk(__p, std::move(__d), __a);
445419#else
446420 _CntrlBlk(__p, __d, __a);
447421#endif // not _LIBCPP_CXX03_LANG
448 __cntrl_ = std::addressof(*__hold2.release());
449#if _LIBCPP_HAS_EXCEPTIONS
450 } catch (...) {
451 __d(__p);
452 throw;
453 }
454#endif // _LIBCPP_HAS_EXCEPTIONS
422 __cntrl_ = std::addressof(*__hold2.release());
423 __guard.__complete();
455424 }
456425
457426 template <class _Yp>
......@@ -514,45 +483,16 @@ public:
514483
515484 template <class _Yp,
516485 class _Dp,
517 __enable_if_t<!is_lvalue_reference<_Dp>::value && __compatible_with<_Yp, _Tp>::value &&
486 __enable_if_t<__compatible_with<_Yp, _Tp>::value &&
518487 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
519488 int> = 0>
520489 _LIBCPP_HIDE_FROM_ABI shared_ptr(unique_ptr<_Yp, _Dp>&& __r) : __ptr_(__r.get()) {
521#if _LIBCPP_STD_VER >= 14
522 if (__ptr_ == nullptr)
523 __cntrl_ = nullptr;
524 else
525#endif
526 {
527 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
528 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT> _CntrlBlk;
529 __cntrl_ = new _CntrlBlk(__r.get(), std::move(__r.get_deleter()), _AllocT());
530 __enable_weak_this(__r.get(), __r.get());
531 }
532 __r.release();
533 }
490 using _AllocT = typename __shared_ptr_default_allocator<_Yp>::type;
491 using _Deleter = _If<is_lvalue_reference<_Dp>::value, reference_wrapper<__libcpp_remove_reference_t<_Dp> >, _Dp>;
492 using _CntrlBlk = __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Deleter, _AllocT>;
534493
535 template <class _Yp,
536 class _Dp,
537 class = void,
538 __enable_if_t<is_lvalue_reference<_Dp>::value && __compatible_with<_Yp, _Tp>::value &&
539 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
540 int> = 0>
541 _LIBCPP_HIDE_FROM_ABI shared_ptr(unique_ptr<_Yp, _Dp>&& __r) : __ptr_(__r.get()) {
542#if _LIBCPP_STD_VER >= 14
543 if (__ptr_ == nullptr)
544 __cntrl_ = nullptr;
545 else
546#endif
547 {
548 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
549 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer,
550 reference_wrapper<__libcpp_remove_reference_t<_Dp> >,
551 _AllocT>
552 _CntrlBlk;
553 __cntrl_ = new _CntrlBlk(__r.get(), std::ref(__r.get_deleter()), _AllocT());
554 __enable_weak_this(__r.get(), __r.get());
555 }
494 __cntrl_ = __ptr_ ? new _CntrlBlk(__r.get(), std::forward<_Dp>(__r.get_deleter()), _AllocT()) : nullptr;
495 __enable_weak_this(__r.get(), __r.get());
556496 __r.release();
557497 }
558498
......@@ -628,37 +568,43 @@ public:
628568 shared_ptr(__p, __d, __a).swap(*this);
629569 }
630570
631 _LIBCPP_HIDE_FROM_ABI element_type* get() const _NOEXCEPT { return __ptr_; }
571 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI element_type* get() const _NOEXCEPT { return __ptr_; }
632572
633 _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT { return *__ptr_; }
573 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT {
574 return *__ptr_;
575 }
634576
635577 _LIBCPP_HIDE_FROM_ABI element_type* operator->() const _NOEXCEPT {
636578 static_assert(!is_array<_Tp>::value, "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
637579 return __ptr_;
638580 }
639581
640 _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; }
582 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT {
583 return __cntrl_ ? __cntrl_->use_count() : 0;
584 }
641585
642586#if _LIBCPP_STD_VER < 20 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE)
643 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT { return use_count() == 1; }
587 [[__nodiscard__]] _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT {
588 return use_count() == 1;
589 }
644590#endif
645591
646592 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return get() != nullptr; }
647593
648594 template <class _Up>
649 _LIBCPP_HIDE_FROM_ABI bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT {
595 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT {
650596 return __cntrl_ < __p.__cntrl_;
651597 }
652598
653599 template <class _Up>
654 _LIBCPP_HIDE_FROM_ABI bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT {
600 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT {
655601 return __cntrl_ < __p.__cntrl_;
656602 }
657603
658604 _LIBCPP_HIDE_FROM_ABI bool __owner_equivalent(const shared_ptr& __p) const { return __cntrl_ == __p.__cntrl_; }
659605
660606#if _LIBCPP_STD_VER >= 17
661 _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const {
607 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const {
662608 static_assert(is_array<_Tp>::value, "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
663609 return __ptr_[__i];
664610 }
......@@ -729,7 +675,7 @@ shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
729675// std::allocate_shared and std::make_shared
730676//
731677template <class _Tp, class _Alloc, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0>
732_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) {
678[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) {
733679 using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
734680 using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
735681 __allocation_guard<_ControlBlockAllocator> __guard(__a, 1);
......@@ -740,21 +686,21 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&
740686}
741687
742688template <class _Tp, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0>
743_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&&... __args) {
689[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&&... __args) {
744690 return std::allocate_shared<_Tp>(allocator<__remove_cv_t<_Tp> >(), std::forward<_Args>(__args)...);
745691}
746692
747693#if _LIBCPP_STD_VER >= 20
748694
749695template <class _Tp, class _Alloc, __enable_if_t<!is_array<_Tp>::value, int> = 0>
750_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
696[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
751697 using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
752698 _ForOverwriteAllocator __alloc(__a);
753699 return std::allocate_shared<_Tp>(__alloc);
754700}
755701
756702template <class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
757_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
703[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
758704 return std::allocate_shared_for_overwrite<_Tp>(allocator<__remove_cv_t<_Tp>>());
759705}
760706
......@@ -946,67 +892,69 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Array> __allocate_shared_bounded_array(const _
946892
947893// bounded array variants
948894template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
949_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a) {
895[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a) {
950896 return std::__allocate_shared_bounded_array<_Tp>(__a);
951897}
952898
953899template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
954_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u) {
900[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
901allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u) {
955902 return std::__allocate_shared_bounded_array<_Tp>(__a, __u);
956903}
957904
958905template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
959_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
906[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
960907 using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
961908 _ForOverwriteAllocator __alloc(__a);
962909 return std::__allocate_shared_bounded_array<_Tp>(__alloc);
963910}
964911
965912template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
966_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared() {
913[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared() {
967914 return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>());
968915}
969916
970917template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
971_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u) {
918[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u) {
972919 return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __u);
973920}
974921
975922template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
976_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
923[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
977924 return std::__allocate_shared_bounded_array<_Tp>(allocator<__for_overwrite_tag>());
978925}
979926
980927// unbounded array variants
981928template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
982_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n) {
929[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n) {
983930 return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
984931}
985932
986933template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
987_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u) {
934[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
935allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u) {
988936 return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u);
989937}
990938
991939template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
992_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n) {
940[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n) {
993941 using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
994942 _ForOverwriteAllocator __alloc(__a);
995943 return std::__allocate_shared_unbounded_array<_Tp>(__alloc, __n);
996944}
997945
998946template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
999_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n) {
947[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n) {
1000948 return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n);
1001949}
1002950
1003951template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
1004_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u) {
952[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u) {
1005953 return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __u);
1006954}
1007955
1008956template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
1009_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) {
957[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) {
1010958 return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n);
1011959}
1012960
......@@ -1135,7 +1083,8 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __
11351083}
11361084
11371085template <class _Tp, class _Up>
1138inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
1086[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
1087static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
11391088 return shared_ptr<_Tp>(__r, static_cast< typename shared_ptr<_Tp>::element_type*>(__r.get()));
11401089}
11411090
......@@ -1143,13 +1092,14 @@ inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(const shared_pt
11431092// We don't backport because it is an evolutionary change.
11441093#if _LIBCPP_STD_VER >= 20
11451094template <class _Tp, class _Up>
1146_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
1095[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
11471096 return shared_ptr<_Tp>(std::move(__r), static_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
11481097}
11491098#endif
11501099
11511100template <class _Tp, class _Up>
1152inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
1101[[__nodiscard__]] inline
1102 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
11531103 typedef typename shared_ptr<_Tp>::element_type _ET;
11541104 _ET* __p = dynamic_cast<_ET*>(__r.get());
11551105 return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
......@@ -1159,14 +1109,14 @@ inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_p
11591109// We don't backport because it is an evolutionary change.
11601110#if _LIBCPP_STD_VER >= 20
11611111template <class _Tp, class _Up>
1162_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
1112[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
11631113 auto* __p = dynamic_cast<typename shared_ptr<_Tp>::element_type*>(__r.get());
11641114 return __p ? shared_ptr<_Tp>(std::move(__r), __p) : shared_ptr<_Tp>();
11651115}
11661116#endif
11671117
11681118template <class _Tp, class _Up>
1169_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
1119[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
11701120 typedef typename shared_ptr<_Tp>::element_type _RTp;
11711121 return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
11721122}
......@@ -1175,13 +1125,13 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>&
11751125// We don't backport because it is an evolutionary change.
11761126#if _LIBCPP_STD_VER >= 20
11771127template <class _Tp, class _Up>
1178_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
1128[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
11791129 return shared_ptr<_Tp>(std::move(__r), const_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
11801130}
11811131#endif
11821132
11831133template <class _Tp, class _Up>
1184_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
1134[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
11851135 return shared_ptr<_Tp>(__r, reinterpret_cast< typename shared_ptr<_Tp>::element_type*>(__r.get()));
11861136}
11871137
......@@ -1189,7 +1139,7 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<
11891139// We don't backport because it is an evolutionary change.
11901140#if _LIBCPP_STD_VER >= 20
11911141template <class _Tp, class _Up>
1192_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
1142[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
11931143 return shared_ptr<_Tp>(std::move(__r), reinterpret_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
11941144}
11951145#endif
......@@ -1197,7 +1147,7 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&&
11971147#if _LIBCPP_HAS_RTTI
11981148
11991149template <class _Dp, class _Tp>
1200inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT {
1150[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT {
12011151 return __p.template __get_deleter<_Dp>();
12021152}
12031153
......@@ -1213,9 +1163,8 @@ public:
12131163#endif
12141164
12151165 // A weak_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
1216 // any bookkeeping, so it's always trivially relocatable. It's also replaceable for the same reason.
1166 // any bookkeeping, so it's always trivially relocatable.
12171167 using __trivially_relocatable _LIBCPP_NODEBUG = weak_ptr;
1218 using __replaceable _LIBCPP_NODEBUG = weak_ptr;
12191168
12201169private:
12211170 element_type* __ptr_;
......@@ -1253,15 +1202,19 @@ public:
12531202 _LIBCPP_HIDE_FROM_ABI void swap(weak_ptr& __r) _NOEXCEPT;
12541203 _LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT;
12551204
1256 _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; }
1257 _LIBCPP_HIDE_FROM_ABI bool expired() const _NOEXCEPT { return __cntrl_ == nullptr || __cntrl_->use_count() == 0; }
1258 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT;
1205 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT {
1206 return __cntrl_ ? __cntrl_->use_count() : 0;
1207 }
1208 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool expired() const _NOEXCEPT {
1209 return __cntrl_ == nullptr || __cntrl_->use_count() == 0;
1210 }
1211 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT;
12591212 template <class _Up>
1260 _LIBCPP_HIDE_FROM_ABI bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT {
1213 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT {
12611214 return __cntrl_ < __r.__cntrl_;
12621215 }
12631216 template <class _Up>
1264 _LIBCPP_HIDE_FROM_ABI bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT {
1217 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT {
12651218 return __cntrl_ < __r.__cntrl_;
12661219 }
12671220
......@@ -1445,13 +1398,15 @@ protected:
14451398 _LIBCPP_HIDE_FROM_ABI ~enable_shared_from_this() {}
14461399
14471400public:
1448 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(__weak_this_); }
1449 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp const> shared_from_this() const { return shared_ptr<const _Tp>(__weak_this_); }
1401 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(__weak_this_); }
1402 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp const> shared_from_this() const {
1403 return shared_ptr<const _Tp>(__weak_this_);
1404 }
14501405
14511406#if _LIBCPP_STD_VER >= 17
1452 _LIBCPP_HIDE_FROM_ABI weak_ptr<_Tp> weak_from_this() _NOEXCEPT { return __weak_this_; }
1407 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI weak_ptr<_Tp> weak_from_this() _NOEXCEPT { return __weak_this_; }
14531408
1454 _LIBCPP_HIDE_FROM_ABI weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT { return __weak_this_; }
1409 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT { return __weak_this_; }
14551410#endif // _LIBCPP_STD_VER >= 17
14561411
14571412 template <class _Up>
......@@ -1468,7 +1423,7 @@ struct hash<shared_ptr<_Tp> > {
14681423 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
14691424#endif
14701425
1471 _LIBCPP_HIDE_FROM_ABI size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT {
1426 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT {
14721427 return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
14731428 }
14741429};
lib/libcxx/include/__memory/temp_value.h+1-2
......@@ -12,7 +12,6 @@
1212#include <__config>
1313#include <__memory/addressof.h>
1414#include <__memory/allocator_traits.h>
15#include <__type_traits/aligned_storage.h>
1615#include <__utility/forward.h>
1716
1817#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -26,7 +25,7 @@ struct __temp_value {
2625 typedef allocator_traits<_Alloc> _Traits;
2726
2827#ifdef _LIBCPP_CXX03_LANG
29 typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v;
28 _ALIGNAS_TYPE(_Tp) char __v[sizeof(_Tp)];
3029#else
3130 union {
3231 _Tp __v;
lib/libcxx/include/__memory/uninitialized_algorithms.h+44-115
......@@ -32,7 +32,6 @@
3232#include <__type_traits/is_trivially_assignable.h>
3333#include <__type_traits/is_trivially_constructible.h>
3434#include <__type_traits/is_trivially_relocatable.h>
35#include <__type_traits/is_unbounded_array.h>
3635#include <__type_traits/remove_const.h>
3736#include <__type_traits/remove_extent.h>
3837#include <__utility/exception_guard.h>
......@@ -61,17 +60,10 @@ template <class _ValueType, class _InputIterator, class _Sentinel1, class _Forwa
6160inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> __uninitialized_copy(
6261 _InputIterator __ifirst, _Sentinel1 __ilast, _ForwardIterator __ofirst, _EndPredicate __stop_copying) {
6362 _ForwardIterator __idx = __ofirst;
64#if _LIBCPP_HAS_EXCEPTIONS
65 try {
66#endif
67 for (; __ifirst != __ilast && !__stop_copying(__idx); ++__ifirst, (void)++__idx)
68 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType(*__ifirst);
69#if _LIBCPP_HAS_EXCEPTIONS
70 } catch (...) {
71 std::__destroy(__ofirst, __idx);
72 throw;
73 }
74#endif
63 auto __guard = std::__make_exception_guard([&] { std::__destroy(__ofirst, __idx); });
64 for (; __ifirst != __ilast && !__stop_copying(__idx); ++__ifirst, (void)++__idx)
65 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType(*__ifirst);
66 __guard.__complete();
7567
7668 return pair<_InputIterator, _ForwardIterator>(std::move(__ifirst), std::move(__idx));
7769}
......@@ -91,17 +83,10 @@ template <class _ValueType, class _InputIterator, class _Size, class _ForwardIte
9183inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator>
9284__uninitialized_copy_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __ofirst, _EndPredicate __stop_copying) {
9385 _ForwardIterator __idx = __ofirst;
94#if _LIBCPP_HAS_EXCEPTIONS
95 try {
96#endif
97 for (; __n > 0 && !__stop_copying(__idx); ++__ifirst, (void)++__idx, (void)--__n)
98 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType(*__ifirst);
99#if _LIBCPP_HAS_EXCEPTIONS
100 } catch (...) {
101 std::__destroy(__ofirst, __idx);
102 throw;
103 }
104#endif
86 auto __guard = std::__make_exception_guard([&] { std::__destroy(__ofirst, __idx); });
87 for (; __n > 0 && !__stop_copying(__idx); ++__ifirst, (void)++__idx, (void)--__n)
88 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType(*__ifirst);
89 __guard.__complete();
10590
10691 return pair<_InputIterator, _ForwardIterator>(std::move(__ifirst), std::move(__idx));
10792}
......@@ -121,17 +106,10 @@ template <class _ValueType, class _ForwardIterator, class _Sentinel, class _Tp>
121106inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
122107__uninitialized_fill(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) {
123108 _ForwardIterator __idx = __first;
124#if _LIBCPP_HAS_EXCEPTIONS
125 try {
126#endif
127 for (; __idx != __last; ++__idx)
128 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType(__x);
129#if _LIBCPP_HAS_EXCEPTIONS
130 } catch (...) {
131 std::__destroy(__first, __idx);
132 throw;
133 }
134#endif
109 auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
110 for (; __idx != __last; ++__idx)
111 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType(__x);
112 __guard.__complete();
135113
136114 return __idx;
137115}
......@@ -149,17 +127,10 @@ template <class _ValueType, class _ForwardIterator, class _Size, class _Tp>
149127inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
150128__uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) {
151129 _ForwardIterator __idx = __first;
152#if _LIBCPP_HAS_EXCEPTIONS
153 try {
154#endif
155 for (; __n > 0; ++__idx, (void)--__n)
156 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType(__x);
157#if _LIBCPP_HAS_EXCEPTIONS
158 } catch (...) {
159 std::__destroy(__first, __idx);
160 throw;
161 }
162#endif
130 auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
131 for (; __n > 0; ++__idx, (void)--__n)
132 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType(__x);
133 __guard.__complete();
163134
164135 return __idx;
165136}
......@@ -178,18 +149,11 @@ uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) {
178149template <class _ValueType, class _ForwardIterator, class _Sentinel>
179150inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
180151__uninitialized_default_construct(_ForwardIterator __first, _Sentinel __last) {
181 auto __idx = __first;
182# if _LIBCPP_HAS_EXCEPTIONS
183 try {
184# endif
185 for (; __idx != __last; ++__idx)
186 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType;
187# if _LIBCPP_HAS_EXCEPTIONS
188 } catch (...) {
189 std::__destroy(__first, __idx);
190 throw;
191 }
192# endif
152 auto __idx = __first;
153 auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
154 for (; __idx != __last; ++__idx)
155 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType;
156 __guard.__complete();
193157
194158 return __idx;
195159}
......@@ -205,17 +169,10 @@ inline _LIBCPP_HIDE_FROM_ABI void uninitialized_default_construct(_ForwardIterat
205169template <class _ValueType, class _ForwardIterator, class _Size>
206170inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator __uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
207171 auto __idx = __first;
208# if _LIBCPP_HAS_EXCEPTIONS
209 try {
210# endif
211 for (; __n > 0; ++__idx, (void)--__n)
212 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType;
213# if _LIBCPP_HAS_EXCEPTIONS
214 } catch (...) {
215 std::__destroy(__first, __idx);
216 throw;
217 }
218# endif
172 auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
173 for (; __n > 0; ++__idx, (void)--__n)
174 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType;
175 __guard.__complete();
219176
220177 return __idx;
221178}
......@@ -231,18 +188,11 @@ inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_default_construct_n(
231188template <class _ValueType, class _ForwardIterator, class _Sentinel>
232189inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
233190__uninitialized_value_construct(_ForwardIterator __first, _Sentinel __last) {
234 auto __idx = __first;
235# if _LIBCPP_HAS_EXCEPTIONS
236 try {
237# endif
238 for (; __idx != __last; ++__idx)
239 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType();
240# if _LIBCPP_HAS_EXCEPTIONS
241 } catch (...) {
242 std::__destroy(__first, __idx);
243 throw;
244 }
245# endif
191 auto __idx = __first;
192 auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
193 for (; __idx != __last; ++__idx)
194 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType();
195 __guard.__complete();
246196
247197 return __idx;
248198}
......@@ -258,17 +208,10 @@ inline _LIBCPP_HIDE_FROM_ABI void uninitialized_value_construct(_ForwardIterator
258208template <class _ValueType, class _ForwardIterator, class _Size>
259209inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator __uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
260210 auto __idx = __first;
261# if _LIBCPP_HAS_EXCEPTIONS
262 try {
263# endif
264 for (; __n > 0; ++__idx, (void)--__n)
265 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType();
266# if _LIBCPP_HAS_EXCEPTIONS
267 } catch (...) {
268 std::__destroy(__first, __idx);
269 throw;
270 }
271# endif
211 auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
212 for (; __n > 0; ++__idx, (void)--__n)
213 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType();
214 __guard.__complete();
272215
273216 return __idx;
274217}
......@@ -293,19 +236,12 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> __uninitiali
293236 _ForwardIterator __ofirst,
294237 _EndPredicate __stop_moving,
295238 _IterMove __iter_move) {
296 auto __idx = __ofirst;
297# if _LIBCPP_HAS_EXCEPTIONS
298 try {
299# endif
300 for (; __ifirst != __ilast && !__stop_moving(__idx); ++__idx, (void)++__ifirst) {
301 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType(__iter_move(__ifirst));
302 }
303# if _LIBCPP_HAS_EXCEPTIONS
304 } catch (...) {
305 std::__destroy(__ofirst, __idx);
306 throw;
239 auto __idx = __ofirst;
240 auto __guard = std::__make_exception_guard([&] { std::__destroy(__ofirst, __idx); });
241 for (; __ifirst != __ilast && !__stop_moving(__idx); ++__idx, (void)++__ifirst) {
242 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType(__iter_move(__ifirst));
307243 }
308# endif
244 __guard.__complete();
309245
310246 return {std::move(__ifirst), std::move(__idx)};
311247}
......@@ -331,18 +267,11 @@ template <class _ValueType,
331267 class _IterMove>
332268inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> __uninitialized_move_n(
333269 _InputIterator __ifirst, _Size __n, _ForwardIterator __ofirst, _EndPredicate __stop_moving, _IterMove __iter_move) {
334 auto __idx = __ofirst;
335# if _LIBCPP_HAS_EXCEPTIONS
336 try {
337# endif
338 for (; __n > 0 && !__stop_moving(__idx); ++__idx, (void)++__ifirst, --__n)
339 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType(__iter_move(__ifirst));
340# if _LIBCPP_HAS_EXCEPTIONS
341 } catch (...) {
342 std::__destroy(__ofirst, __idx);
343 throw;
344 }
345# endif
270 auto __idx = __ofirst;
271 auto __guard = std::__make_exception_guard([&] { std::__destroy(__ofirst, __idx); });
272 for (; __n > 0 && !__stop_moving(__idx); ++__idx, (void)++__ifirst, --__n)
273 ::new (static_cast<void*>(std::addressof(*__idx))) _ValueType(__iter_move(__ifirst));
274 __guard.__complete();
346275
347276 return {std::move(__ifirst), std::move(__idx)};
348277}
lib/libcxx/include/__memory/unique_ptr.h+14-16
......@@ -32,18 +32,15 @@
3232#include <__type_traits/integral_constant.h>
3333#include <__type_traits/is_array.h>
3434#include <__type_traits/is_assignable.h>
35#include <__type_traits/is_bounded_array.h>
3635#include <__type_traits/is_constant_evaluated.h>
3736#include <__type_traits/is_constructible.h>
3837#include <__type_traits/is_convertible.h>
3938#include <__type_traits/is_function.h>
4039#include <__type_traits/is_pointer.h>
4140#include <__type_traits/is_reference.h>
42#include <__type_traits/is_replaceable.h>
4341#include <__type_traits/is_same.h>
4442#include <__type_traits/is_swappable.h>
4543#include <__type_traits/is_trivially_relocatable.h>
46#include <__type_traits/is_unbounded_array.h>
4744#include <__type_traits/is_void.h>
4845#include <__type_traits/remove_extent.h>
4946#include <__type_traits/type_identity.h>
......@@ -145,8 +142,6 @@ public:
145142 __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,
146143 unique_ptr,
147144 void>;
148 using __replaceable _LIBCPP_NODEBUG =
149 __conditional_t<__is_replaceable_v<pointer> && __is_replaceable_v<deleter_type>, unique_ptr, void>;
150145
151146private:
152147 _LIBCPP_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_);
......@@ -263,14 +258,17 @@ public:
263258 return *this;
264259 }
265260
266 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const
261 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const
267262 _NOEXCEPT_(_NOEXCEPT_(*std::declval<pointer>())) {
268263 return *__ptr_;
269264 }
270265 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_; }
271 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }
272 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __deleter_; }
273 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT {
266 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }
267 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT {
268 return __deleter_;
269 }
270 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type&
271 get_deleter() const _NOEXCEPT {
274272 return __deleter_;
275273 }
276274 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {
......@@ -413,8 +411,6 @@ public:
413411 __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,
414412 unique_ptr,
415413 void>;
416 using __replaceable _LIBCPP_NODEBUG =
417 __conditional_t<__is_replaceable_v<pointer> && __is_replaceable_v<deleter_type>, unique_ptr, void>;
418414
419415private:
420416 template <class _Up, class _OtherDeleter>
......@@ -755,12 +751,13 @@ operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
755751#if _LIBCPP_STD_VER >= 14
756752
757753template <class _Tp, class... _Args, enable_if_t<!is_array<_Tp>::value, int> = 0>
758inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(_Args&&... __args) {
754[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
755_LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(_Args&&... __args) {
759756 return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...));
760757}
761758
762759template <class _Tp, enable_if_t<__is_unbounded_array_v<_Tp>, int> = 0>
763inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(size_t __n) {
760[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(size_t __n) {
764761 typedef __remove_extent_t<_Tp> _Up;
765762 return unique_ptr<_Tp>(__private_constructor_tag(), new _Up[__n](), __n);
766763}
......@@ -773,12 +770,13 @@ void make_unique(_Args&&...) = delete;
773770#if _LIBCPP_STD_VER >= 20
774771
775772template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
776_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite() {
773[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite() {
777774 return unique_ptr<_Tp>(new _Tp);
778775}
779776
780777template <class _Tp, enable_if_t<is_unbounded_array_v<_Tp>, int> = 0>
781_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite(size_t __n) {
778[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp>
779make_unique_for_overwrite(size_t __n) {
782780 return unique_ptr<_Tp>(__private_constructor_tag(), new __remove_extent_t<_Tp>[__n], __n);
783781}
784782
......@@ -802,7 +800,7 @@ struct hash<__enable_hash_helper< unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp,
802800 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
803801#endif
804802
805 _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const {
803 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const {
806804 typedef typename unique_ptr<_Tp, _Dp>::pointer pointer;
807805 return hash<pointer>()(__ptr.get());
808806 }
lib/libcxx/include/__memory/uses_allocator_construction.h+1
......@@ -17,6 +17,7 @@
1717#include <__type_traits/remove_cv.h>
1818#include <__utility/declval.h>
1919#include <__utility/pair.h>
20#include <__utility/piecewise_construct.h>
2021#include <tuple>
2122
2223#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
lib/libcxx/include/__memory_resource/memory_resource.h+4-2
......@@ -42,7 +42,9 @@ public:
4242 do_deallocate(__p, __bytes, __align);
4343 }
4444
45 _LIBCPP_HIDE_FROM_ABI bool is_equal(const memory_resource& __other) const noexcept { return do_is_equal(__other); }
45 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_equal(const memory_resource& __other) const noexcept {
46 return do_is_equal(__other);
47 }
4648
4749private:
4850 virtual void* do_allocate(size_t, size_t) = 0;
......@@ -68,7 +70,7 @@ operator!=(const memory_resource& __lhs, const memory_resource& __rhs) noexcept
6870
6971// [mem.res.global]
7072
71[[__gnu__::__returns_nonnull__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource*
73[[nodiscard, __gnu__::__returns_nonnull__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource*
7274get_default_resource() noexcept;
7375
7476[[__gnu__::__returns_nonnull__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource*
lib/libcxx/include/__memory_resource/monotonic_buffer_resource.h+1-1
......@@ -93,7 +93,7 @@ public:
9393 }
9494 }
9595
96 _LIBCPP_HIDE_FROM_ABI memory_resource* upstream_resource() const { return __res_; }
96 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI memory_resource* upstream_resource() const { return __res_; }
9797
9898protected:
9999 void* do_allocate(size_t __bytes, size_t __alignment) override; // key function
lib/libcxx/include/__memory_resource/polymorphic_allocator.h+13-8
......@@ -18,6 +18,7 @@
1818#include <__new/exceptions.h>
1919#include <__new/placement_new_delete.h>
2020#include <__utility/exception_guard.h>
21#include <__utility/piecewise_construct.h>
2122#include <limits>
2223#include <tuple>
2324
......@@ -50,7 +51,9 @@ public:
5051
5152 _LIBCPP_HIDE_FROM_ABI polymorphic_allocator() noexcept : __res_(std::pmr::get_default_resource()) {}
5253
53 _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(memory_resource* __r) noexcept : __res_(__r) {}
54 _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(memory_resource* _LIBCPP_DIAGNOSE_NULLPTR __r) noexcept : __res_(__r) {
55 _LIBCPP_ASSERT_NON_NULL(__r, "Attempted to pass a nullptr resource to polymorphic_alloator");
56 }
5457
5558 _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(const polymorphic_allocator&) = default;
5659
......@@ -133,10 +136,10 @@ public:
133136 piecewise_construct,
134137 __transform_tuple(typename __uses_alloc_ctor< _T1, polymorphic_allocator&, _Args1... >::type(),
135138 std::move(__x),
136 typename __make_tuple_indices<sizeof...(_Args1)>::type{}),
139 make_index_sequence<sizeof...(_Args1)>()),
137140 __transform_tuple(typename __uses_alloc_ctor< _T2, polymorphic_allocator&, _Args2... >::type(),
138141 std::move(__y),
139 typename __make_tuple_indices<sizeof...(_Args2)>::type{}));
142 make_index_sequence<sizeof...(_Args2)>()));
140143 }
141144
142145 template <class _T1, class _T2>
......@@ -170,11 +173,13 @@ public:
170173 __p->~_Tp();
171174 }
172175
173 _LIBCPP_HIDE_FROM_ABI polymorphic_allocator select_on_container_copy_construction() const noexcept {
176 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI polymorphic_allocator select_on_container_copy_construction() const noexcept {
174177 return polymorphic_allocator();
175178 }
176179
177 _LIBCPP_HIDE_FROM_ABI memory_resource* resource() const noexcept { return __res_; }
180 [[nodiscard, __gnu__::__returns_nonnull__]] _LIBCPP_HIDE_FROM_ABI memory_resource* resource() const noexcept {
181 return __res_;
182 }
178183
179184 _LIBCPP_HIDE_FROM_ABI friend bool
180185 operator==(const polymorphic_allocator& __lhs, const polymorphic_allocator& __rhs) noexcept {
......@@ -192,20 +197,20 @@ public:
192197private:
193198 template <class... _Args, size_t... _Is>
194199 _LIBCPP_HIDE_FROM_ABI tuple<_Args&&...>
195 __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, __tuple_indices<_Is...>) {
200 __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, index_sequence<_Is...>) {
196201 return std::forward_as_tuple(std::get<_Is>(std::move(__t))...);
197202 }
198203
199204 template <class... _Args, size_t... _Is>
200205 _LIBCPP_HIDE_FROM_ABI tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...>
201 __transform_tuple(integral_constant<int, 1>, tuple<_Args...>&& __t, __tuple_indices<_Is...>) {
206 __transform_tuple(integral_constant<int, 1>, tuple<_Args...>&& __t, index_sequence<_Is...>) {
202207 using _Tup = tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...>;
203208 return _Tup(allocator_arg, *this, std::get<_Is>(std::move(__t))...);
204209 }
205210
206211 template <class... _Args, size_t... _Is>
207212 _LIBCPP_HIDE_FROM_ABI tuple<_Args&&..., polymorphic_allocator&>
208 __transform_tuple(integral_constant<int, 2>, tuple<_Args...>&& __t, __tuple_indices<_Is...>) {
213 __transform_tuple(integral_constant<int, 2>, tuple<_Args...>&& __t, index_sequence<_Is...>) {
209214 using _Tup = tuple<_Args&&..., polymorphic_allocator&>;
210215 return _Tup(std::get<_Is>(std::move(__t))..., *this);
211216 }
lib/libcxx/include/__memory_resource/pool_options.h+1-1
......@@ -24,7 +24,7 @@ namespace pmr {
2424
2525// [mem.res.pool.options]
2626
27struct _LIBCPP_EXPORTED_FROM_ABI pool_options {
27struct pool_options {
2828 size_t max_blocks_per_chunk = 0;
2929 size_t largest_required_pool_block = 0;
3030};
lib/libcxx/include/__memory_resource/synchronized_pool_resource.h+4-2
......@@ -56,9 +56,11 @@ public:
5656 __unsync_.release();
5757 }
5858
59 _LIBCPP_HIDE_FROM_ABI memory_resource* upstream_resource() const { return __unsync_.upstream_resource(); }
59 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI memory_resource* upstream_resource() const {
60 return __unsync_.upstream_resource();
61 }
6062
61 _LIBCPP_HIDE_FROM_ABI pool_options options() const { return __unsync_.options(); }
63 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI pool_options options() const { return __unsync_.options(); }
6264
6365protected:
6466 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void* do_allocate(size_t __bytes, size_t __align) override {
lib/libcxx/include/__memory_resource/unsynchronized_pool_resource.h+1-1
......@@ -76,7 +76,7 @@ public:
7676
7777 void release();
7878
79 _LIBCPP_HIDE_FROM_ABI memory_resource* upstream_resource() const { return __res_; }
79 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI memory_resource* upstream_resource() const { return __res_; }
8080
8181 [[__gnu__::__pure__]] pool_options options() const;
8282
lib/libcxx/include/__mutex/mutex.h+2-2
......@@ -37,11 +37,11 @@ public:
3737# endif
3838
3939 _LIBCPP_ACQUIRE_CAPABILITY() void lock();
40 _LIBCPP_TRY_ACQUIRE_CAPABILITY(true) bool try_lock() _NOEXCEPT;
40 [[__nodiscard__]] _LIBCPP_TRY_ACQUIRE_CAPABILITY(true) bool try_lock() _NOEXCEPT;
4141 _LIBCPP_RELEASE_CAPABILITY void unlock() _NOEXCEPT;
4242
4343 typedef __libcpp_mutex_t* native_handle_type;
44 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
44 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
4545};
4646
4747static_assert(is_nothrow_default_constructible<mutex>::value, "the default constructor for std::mutex must be nothrow");
lib/libcxx/include/__mutex/once_flag.h+14-11
......@@ -10,12 +10,11 @@
1010#define _LIBCPP___MUTEX_ONCE_FLAG_H
1111
1212#include <__config>
13#include <__functional/invoke.h>
1413#include <__memory/addressof.h>
15#include <__memory/shared_count.h> // __libcpp_acquire_load
16#include <__tuple/tuple_indices.h>
1714#include <__tuple/tuple_size.h>
15#include <__type_traits/invoke.h>
1816#include <__utility/forward.h>
17#include <__utility/integer_sequence.h>
1918#include <__utility/move.h>
2019#include <cstdint>
2120#ifndef _LIBCPP_CXX03_LANG
......@@ -88,14 +87,9 @@ public:
8887 _LIBCPP_HIDE_FROM_ABI explicit __call_once_param(_Fp& __f) : __f_(__f) {}
8988
9089 _LIBCPP_HIDE_FROM_ABI void operator()() {
91 typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index;
92 __execute(_Index());
93 }
94
95private:
96 template <size_t... _Indices>
97 _LIBCPP_HIDE_FROM_ABI void __execute(__tuple_indices<_Indices...>) {
98 std::__invoke(std::get<0>(std::move(__f_)), std::get<_Indices>(std::move(__f_))...);
90 [&]<size_t... _Indices>(__index_sequence<_Indices...>) -> void {
91 std::__invoke(std::get<_Indices>(std::move(__f_))...);
92 }(__make_index_sequence<tuple_size<_Fp>::value>());
9993 }
10094};
10195
......@@ -121,6 +115,15 @@ void _LIBCPP_HIDE_FROM_ABI __call_once_proxy(void* __vp) {
121115
122116_LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile once_flag::_State_type&, void*, void (*)(void*));
123117
118template <class _ValueType>
119inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_acquire_load(_ValueType const* __value) {
120#if _LIBCPP_HAS_THREADS
121 return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
122#else
123 return *__value;
124#endif
125}
126
124127#ifndef _LIBCPP_CXX03_LANG
125128
126129template <class _Callable, class... _Args>
lib/libcxx/include/__mutex/tag_types.h+3-3
......@@ -17,15 +17,15 @@
1717
1818_LIBCPP_BEGIN_NAMESPACE_STD
1919
20struct _LIBCPP_EXPORTED_FROM_ABI defer_lock_t {
20struct defer_lock_t {
2121 explicit defer_lock_t() = default;
2222};
2323
24struct _LIBCPP_EXPORTED_FROM_ABI try_to_lock_t {
24struct try_to_lock_t {
2525 explicit try_to_lock_t() = default;
2626};
2727
28struct _LIBCPP_EXPORTED_FROM_ABI adopt_lock_t {
28struct adopt_lock_t {
2929 explicit adopt_lock_t() = default;
3030};
3131
lib/libcxx/include/__mutex/unique_lock.h+8-7
......@@ -15,6 +15,7 @@
1515#include <__memory/addressof.h>
1616#include <__mutex/tag_types.h>
1717#include <__system_error/throw_system_error.h>
18#include <__utility/move.h>
1819#include <__utility/swap.h>
1920#include <cerrno>
2021
......@@ -22,6 +23,9 @@
2223# pragma GCC system_header
2324#endif
2425
26_LIBCPP_PUSH_MACROS
27#include <__undef_macros>
28
2529_LIBCPP_BEGIN_NAMESPACE_STD
2630
2731template <class _Mutex>
......@@ -74,13 +78,8 @@ public:
7478 }
7579
7680 _LIBCPP_HIDE_FROM_ABI unique_lock& operator=(unique_lock&& __u) _NOEXCEPT {
77 if (__owns_)
78 __m_->unlock();
79
80 __m_ = __u.__m_;
81 __owns_ = __u.__owns_;
82 __u.__m_ = nullptr;
83 __u.__owns_ = false;
81 if (this != std::addressof(__u))
82 unique_lock(std::move(__u)).swap(*this);
8483 return *this;
8584 }
8685
......@@ -170,4 +169,6 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(unique_lock<_Mutex>& __x, unique_lock<_Mu
170169
171170_LIBCPP_END_NAMESPACE_STD
172171
172_LIBCPP_POP_MACROS
173
173174#endif // _LIBCPP___MUTEX_UNIQUE_LOCK_H
lib/libcxx/include/__new/align_val_t.h+6
......@@ -16,6 +16,12 @@
1616# pragma GCC system_header
1717#endif
1818
19// <vcruntime_exception.h> defines its own std::align_val_t type,
20// which we use in order to be ABI-compatible with other STLs on Windows.
21#if _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION && defined(_LIBCPP_ABI_VCRUNTIME)
22# include <vcruntime_new.h>
23#endif
24
1925_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
2026#if _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION && !defined(_LIBCPP_ABI_VCRUNTIME)
2127# ifndef _LIBCPP_CXX03_LANG
lib/libcxx/include/__new/allocate.h+1-2
......@@ -13,7 +13,6 @@
1313#include <__cstddef/max_align_t.h>
1414#include <__cstddef/size_t.h>
1515#include <__new/align_val_t.h>
16#include <__new/global_new_delete.h> // for _LIBCPP_HAS_SIZED_DEALLOCATION
1716#include <__type_traits/type_identity.h>
1817#include <__utility/element_count.h>
1918
......@@ -43,7 +42,7 @@ __libcpp_allocate(__element_count __n, [[__maybe_unused__]] size_t __align = _LI
4342 return static_cast<_Tp*>(__builtin_operator_new(__size));
4443}
4544
46#if _LIBCPP_HAS_SIZED_DEALLOCATION
45#if defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309L
4746# define _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(...) __VA_ARGS__
4847#else
4948# define _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(...) /* nothing */
lib/libcxx/include/__new/exceptions.h+8-2
......@@ -17,6 +17,12 @@
1717# pragma GCC system_header
1818#endif
1919
20// <vcruntime_exception.h> defines its own std::bad_alloc type,
21// which we use in order to be ABI-compatible with other STLs on Windows.
22#if defined(_LIBCPP_ABI_VCRUNTIME)
23# include <vcruntime_exception.h>
24#endif
25
2026_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
2127#if !defined(_LIBCPP_ABI_VCRUNTIME)
2228
......@@ -26,7 +32,7 @@ public:
2632 _LIBCPP_HIDE_FROM_ABI bad_alloc(const bad_alloc&) _NOEXCEPT = default;
2733 _LIBCPP_HIDE_FROM_ABI bad_alloc& operator=(const bad_alloc&) _NOEXCEPT = default;
2834 ~bad_alloc() _NOEXCEPT override;
29 const char* what() const _NOEXCEPT override;
35 [[__nodiscard__]] const char* what() const _NOEXCEPT override;
3036};
3137
3238class _LIBCPP_EXPORTED_FROM_ABI bad_array_new_length : public bad_alloc {
......@@ -35,7 +41,7 @@ public:
3541 _LIBCPP_HIDE_FROM_ABI bad_array_new_length(const bad_array_new_length&) _NOEXCEPT = default;
3642 _LIBCPP_HIDE_FROM_ABI bad_array_new_length& operator=(const bad_array_new_length&) _NOEXCEPT = default;
3743 ~bad_array_new_length() _NOEXCEPT override;
38 const char* what() const _NOEXCEPT override;
44 [[__nodiscard__]] const char* what() const _NOEXCEPT override;
3945};
4046
4147#elif defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 // !_LIBCPP_ABI_VCRUNTIME
lib/libcxx/include/__new/global_new_delete.h+4-11
......@@ -12,7 +12,6 @@
1212#include <__config>
1313#include <__cstddef/size_t.h>
1414#include <__new/align_val_t.h>
15#include <__new/exceptions.h>
1615#include <__new/nothrow_t.h>
1716
1817#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -25,12 +24,6 @@
2524# define _THROW_BAD_ALLOC
2625#endif
2726
28#if defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309L
29# define _LIBCPP_HAS_SIZED_DEALLOCATION 1
30#else
31# define _LIBCPP_HAS_SIZED_DEALLOCATION 0
32#endif
33
3427#if defined(_LIBCPP_ABI_VCRUNTIME)
3528# include <new.h>
3629#else
......@@ -39,7 +32,7 @@
3932 _LIBCPP_NOALIAS;
4033_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p) _NOEXCEPT;
4134_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
42# if _LIBCPP_HAS_SIZED_DEALLOCATION
35# if defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309L
4336_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
4437# endif
4538
......@@ -48,7 +41,7 @@ _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::size_t __sz) _
4841 _LIBCPP_NOALIAS;
4942_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p) _NOEXCEPT;
5043_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
51# if _LIBCPP_HAS_SIZED_DEALLOCATION
44# if defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309L
5245_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;
5346# endif
5447
......@@ -58,7 +51,7 @@ _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::size_t __sz)
5851operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS;
5952_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t) _NOEXCEPT;
6053_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
61# if _LIBCPP_HAS_SIZED_DEALLOCATION
54# if defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309L
6255_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
6356# endif
6457
......@@ -68,7 +61,7 @@ operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
6861operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS;
6962_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t) _NOEXCEPT;
7063_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
71# if _LIBCPP_HAS_SIZED_DEALLOCATION
64# if defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309L
7265_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
7366# endif
7467# endif
lib/libcxx/include/__new/interference_size.h-4
......@@ -20,13 +20,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2020
2121#if _LIBCPP_STD_VER >= 17
2222
23# if defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
24
2523inline constexpr size_t hardware_destructive_interference_size = __GCC_DESTRUCTIVE_SIZE;
2624inline constexpr size_t hardware_constructive_interference_size = __GCC_CONSTRUCTIVE_SIZE;
2725
28# endif // defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
29
3026#endif // _LIBCPP_STD_VER >= 17
3127
3228_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__new/launder.h+3-5
......@@ -10,8 +10,6 @@
1010#define _LIBCPP___NEW_LAUNDER_H
1111
1212#include <__config>
13#include <__type_traits/is_function.h>
14#include <__type_traits/is_void.h>
1513
1614#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1715# pragma GCC system_header
......@@ -20,15 +18,15 @@
2018_LIBCPP_BEGIN_NAMESPACE_STD
2119template <class _Tp>
2220[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT {
23 static_assert(!(is_function<_Tp>::value), "can't launder functions");
24 static_assert(!is_void<_Tp>::value, "can't launder cv-void");
21 // The compiler diagnoses misuses of __builtin_launder, so we don't need to add any static_asserts
22 // to implement the Mandates.
2523 return __builtin_launder(__p);
2624}
2725
2826#if _LIBCPP_STD_VER >= 17
2927template <class _Tp>
3028[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp* launder(_Tp* __p) noexcept {
31 return std::__launder(__p);
29 return __builtin_launder(__p);
3230}
3331#endif
3432_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__new/nothrow_t.h+1-1
......@@ -19,7 +19,7 @@
1919# include <new.h>
2020#else
2121_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
22struct _LIBCPP_EXPORTED_FROM_ABI nothrow_t {
22struct nothrow_t {
2323 explicit nothrow_t() = default;
2424};
2525extern _LIBCPP_EXPORTED_FROM_ABI const nothrow_t nothrow;
lib/libcxx/include/__numeric/gcd_lcm.h+24-34
......@@ -33,28 +33,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3333
3434#if _LIBCPP_STD_VER >= 17
3535
36template <typename _Result, typename _Source, bool _IsSigned = is_signed<_Source>::value>
37struct __ct_abs;
38
39template <typename _Result, typename _Source>
40struct __ct_abs<_Result, _Source, true> {
41 constexpr _LIBCPP_HIDE_FROM_ABI _Result operator()(_Source __t) const noexcept {
36template <class _Result, class _Source>
37constexpr _LIBCPP_HIDE_FROM_ABI _Result __abs_in_type(_Source __t) noexcept {
38 if constexpr (is_signed_v<_Source>) {
4239 if (__t >= 0)
4340 return __t;
4441 if (__t == numeric_limits<_Source>::min())
4542 return -static_cast<_Result>(__t);
4643 return -__t;
44 } else {
45 return __t;
4746 }
48};
49
50template <typename _Result, typename _Source>
51struct __ct_abs<_Result, _Source, false> {
52 constexpr _LIBCPP_HIDE_FROM_ABI _Result operator()(_Source __t) const noexcept { return __t; }
53};
47}
5448
55template <class _Tp>
56constexpr _LIBCPP_HIDDEN _Tp __gcd(_Tp __a, _Tp __b) {
57 static_assert(!is_signed<_Tp>::value, "");
49template <class _Tp, class _Up>
50constexpr _LIBCPP_HIDE_FROM_ABI common_type_t<_Tp, _Up> gcd(_Tp __m, _Up __n) {
51 static_assert(is_integral<_Tp>::value && is_integral<_Up>::value, "Arguments to gcd must be integer types");
52 static_assert(!is_same<__remove_cv_t<_Tp>, bool>::value, "First argument to gcd cannot be bool");
53 static_assert(!is_same<__remove_cv_t<_Up>, bool>::value, "Second argument to gcd cannot be bool");
54 using _Rp = common_type_t<_Tp, _Up>;
55 using _Wp = make_unsigned_t<_Rp>;
5856
5957 // Using Binary GCD algorithm https://en.wikipedia.org/wiki/Binary_GCD_algorithm, based on an implementation
6058 // from https://lemire.me/blog/2024/04/13/greatest-common-divisor-the-extended-euclidean-algorithm-and-speed/
......@@ -67,22 +65,25 @@ constexpr _LIBCPP_HIDDEN _Tp __gcd(_Tp __a, _Tp __b) {
6765 //
6866 // And standard gcd algorithm where instead of modulo, minus is used.
6967
68 auto __a = static_cast<_Wp>(std::__abs_in_type<_Rp>(__m));
69 auto __b = static_cast<_Wp>(std::__abs_in_type<_Rp>(__n));
70
7071 if (__a < __b) {
71 _Tp __tmp = __b;
72 _Wp __tmp = __b;
7273 __b = __a;
7374 __a = __tmp;
7475 }
7576 if (__b == 0)
76 return __a;
77 return static_cast<_Rp>(__a);
7778 __a %= __b; // Make both argument of the same size, and early result in the easy case.
7879 if (__a == 0)
79 return __b;
80 return static_cast<_Rp>(__b);
8081
81 _Tp __c = __a | __b;
82 _Wp __c = __a | __b;
8283 int __shift = std::__countr_zero(__c);
8384 __a >>= std::__countr_zero(__a);
8485 do {
85 _Tp __t = __b >> std::__countr_zero(__b);
86 _Wp __t = __b >> std::__countr_zero(__b);
8687 if (__a > __t) {
8788 __b = __a - __t;
8889 __a = __t;
......@@ -90,18 +91,7 @@ constexpr _LIBCPP_HIDDEN _Tp __gcd(_Tp __a, _Tp __b) {
9091 __b = __t - __a;
9192 }
9293 } while (__b != 0);
93 return __a << __shift;
94}
95
96template <class _Tp, class _Up>
97constexpr _LIBCPP_HIDE_FROM_ABI common_type_t<_Tp, _Up> gcd(_Tp __m, _Up __n) {
98 static_assert(is_integral<_Tp>::value && is_integral<_Up>::value, "Arguments to gcd must be integer types");
99 static_assert(!is_same<__remove_cv_t<_Tp>, bool>::value, "First argument to gcd cannot be bool");
100 static_assert(!is_same<__remove_cv_t<_Up>, bool>::value, "Second argument to gcd cannot be bool");
101 using _Rp = common_type_t<_Tp, _Up>;
102 using _Wp = make_unsigned_t<_Rp>;
103 return static_cast<_Rp>(
104 std::__gcd(static_cast<_Wp>(__ct_abs<_Rp, _Tp>()(__m)), static_cast<_Wp>(__ct_abs<_Rp, _Up>()(__n))));
94 return static_cast<_Rp>(__a << __shift);
10595}
10696
10797template <class _Tp, class _Up>
......@@ -113,8 +103,8 @@ constexpr _LIBCPP_HIDE_FROM_ABI common_type_t<_Tp, _Up> lcm(_Tp __m, _Up __n) {
113103 return 0;
114104
115105 using _Rp = common_type_t<_Tp, _Up>;
116 _Rp __val1 = __ct_abs<_Rp, _Tp>()(__m) / std::gcd(__m, __n);
117 _Rp __val2 = __ct_abs<_Rp, _Up>()(__n);
106 _Rp __val1 = std::__abs_in_type<_Rp>(__m) / std::gcd(__m, __n);
107 _Rp __val2 = std::__abs_in_type<_Rp>(__n);
118108 _Rp __res;
119109 [[maybe_unused]] bool __overflow = __builtin_mul_overflow(__val1, __val2, std::addressof(__res));
120110 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(!__overflow, "Overflow in lcm");
lib/libcxx/include/__numeric/midpoint.h+9-14
......@@ -12,16 +12,13 @@
1212
1313#include <__config>
1414#include <__cstddef/ptrdiff_t.h>
15#include <__type_traits/enable_if.h>
1615#include <__type_traits/is_floating_point.h>
1716#include <__type_traits/is_integral.h>
18#include <__type_traits/is_null_pointer.h>
1917#include <__type_traits/is_object.h>
20#include <__type_traits/is_pointer.h>
2118#include <__type_traits/is_same.h>
2219#include <__type_traits/is_void.h>
2320#include <__type_traits/make_unsigned.h>
24#include <__type_traits/remove_pointer.h>
21#include <__type_traits/remove_cv.h>
2522#include <limits>
2623
2724#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -35,8 +32,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3532
3633#if _LIBCPP_STD_VER >= 20
3734template <class _Tp>
38_LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<is_integral_v<_Tp> && !is_same_v<bool, _Tp> && !is_null_pointer_v<_Tp>, _Tp>
39midpoint(_Tp __a, _Tp __b) noexcept _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK {
35 requires(is_integral_v<_Tp> && !is_same_v<remove_cv_t<_Tp>, bool>)
36[[nodiscard]]
37_LIBCPP_HIDE_FROM_ABI constexpr _Tp midpoint(_Tp __a, _Tp __b) noexcept _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK {
4038 using _Up = make_unsigned_t<_Tp>;
4139 constexpr _Up __bitshift = numeric_limits<_Up>::digits - 1;
4240
......@@ -48,23 +46,20 @@ midpoint(_Tp __a, _Tp __b) noexcept _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
4846 return __a + __half_diff;
4947}
5048
51template <class _Tp, enable_if_t<is_object_v<_Tp> && !is_void_v<_Tp> && (sizeof(_Tp) > 0), int> = 0>
52_LIBCPP_HIDE_FROM_ABI constexpr _Tp* midpoint(_Tp* __a, _Tp* __b) noexcept {
49template <class _Tp>
50 requires(is_object_v<_Tp> && (sizeof(_Tp) > 0))
51[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp* midpoint(_Tp* __a, _Tp* __b) noexcept {
5352 return __a + std::midpoint(ptrdiff_t(0), __b - __a);
5453}
5554
56template <typename _Tp>
57_LIBCPP_HIDE_FROM_ABI constexpr int __sign(_Tp __val) {
58 return (_Tp(0) < __val) - (__val < _Tp(0));
59}
60
6155template <typename _Fp>
6256_LIBCPP_HIDE_FROM_ABI constexpr _Fp __fp_abs(_Fp __f) {
6357 return __f >= 0 ? __f : -__f;
6458}
6559
6660template <class _Fp>
67_LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<is_floating_point_v<_Fp>, _Fp> midpoint(_Fp __a, _Fp __b) noexcept {
61 requires(is_floating_point_v<_Fp>)
62[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Fp midpoint(_Fp __a, _Fp __b) noexcept {
6863 constexpr _Fp __lo = numeric_limits<_Fp>::min() * 2;
6964 constexpr _Fp __hi = numeric_limits<_Fp>::max() / 2;
7065
lib/libcxx/include/__numeric/pstl.h+2-2
......@@ -70,7 +70,7 @@ template <class _ExecutionPolicy,
7070 class _ForwardIterator,
7171 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
7272 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
73_LIBCPP_HIDE_FROM_ABI __iter_value_type<_ForwardIterator>
73_LIBCPP_HIDE_FROM_ABI __iterator_value_type<_ForwardIterator>
7474reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last) {
7575 _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "reduce requires ForwardIterators");
7676 using _Implementation = __pstl::__dispatch<__pstl::__reduce, __pstl::__current_configuration, _RawPolicy>;
......@@ -78,7 +78,7 @@ reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator _
7878 std::forward<_ExecutionPolicy>(__policy),
7979 std::move(__first),
8080 std::move(__last),
81 __iter_value_type<_ForwardIterator>(),
81 __iterator_value_type<_ForwardIterator>(),
8282 plus{});
8383}
8484
lib/libcxx/include/__numeric/saturation_arithmetic.h+13-5
......@@ -30,6 +30,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3030
3131template <__signed_or_unsigned_integer _Tp>
3232_LIBCPP_HIDE_FROM_ABI constexpr _Tp __add_sat(_Tp __x, _Tp __y) noexcept {
33# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 2101
34 return __builtin_elementwise_add_sat(__x, __y);
35# else
3336 if (_Tp __sum; !__builtin_add_overflow(__x, __y, std::addressof(__sum)))
3437 return __sum;
3538 // Handle overflow
......@@ -44,10 +47,14 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp __add_sat(_Tp __x, _Tp __y) noexcept {
4447 // Overflows if (x < 0 && y < 0)
4548 return std::numeric_limits<_Tp>::min();
4649 }
50# endif
4751}
4852
4953template <__signed_or_unsigned_integer _Tp>
5054_LIBCPP_HIDE_FROM_ABI constexpr _Tp __sub_sat(_Tp __x, _Tp __y) noexcept {
55# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 2101
56 return __builtin_elementwise_sub_sat(__x, __y);
57# else
5158 if (_Tp __sub; !__builtin_sub_overflow(__x, __y, std::addressof(__sub)))
5259 return __sub;
5360 // Handle overflow
......@@ -63,6 +70,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp __sub_sat(_Tp __x, _Tp __y) noexcept {
6370 // Overflows if (x < 0 && y > 0)
6471 return std::numeric_limits<_Tp>::min();
6572 }
73# endif
6674}
6775
6876template <__signed_or_unsigned_integer _Tp>
......@@ -113,27 +121,27 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Rp __saturate_cast(_Tp __x) noexcept {
113121#if _LIBCPP_STD_VER >= 26
114122
115123template <__signed_or_unsigned_integer _Tp>
116_LIBCPP_HIDE_FROM_ABI constexpr _Tp add_sat(_Tp __x, _Tp __y) noexcept {
124[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp add_sat(_Tp __x, _Tp __y) noexcept {
117125 return std::__add_sat(__x, __y);
118126}
119127
120128template <__signed_or_unsigned_integer _Tp>
121_LIBCPP_HIDE_FROM_ABI constexpr _Tp sub_sat(_Tp __x, _Tp __y) noexcept {
129[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp sub_sat(_Tp __x, _Tp __y) noexcept {
122130 return std::__sub_sat(__x, __y);
123131}
124132
125133template <__signed_or_unsigned_integer _Tp>
126_LIBCPP_HIDE_FROM_ABI constexpr _Tp mul_sat(_Tp __x, _Tp __y) noexcept {
134[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp mul_sat(_Tp __x, _Tp __y) noexcept {
127135 return std::__mul_sat(__x, __y);
128136}
129137
130138template <__signed_or_unsigned_integer _Tp>
131_LIBCPP_HIDE_FROM_ABI constexpr _Tp div_sat(_Tp __x, _Tp __y) noexcept {
139[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp div_sat(_Tp __x, _Tp __y) noexcept {
132140 return std::__div_sat(__x, __y);
133141}
134142
135143template <__signed_or_unsigned_integer _Rp, __signed_or_unsigned_integer _Tp>
136_LIBCPP_HIDE_FROM_ABI constexpr _Rp saturate_cast(_Tp __x) noexcept {
144[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Rp saturate_cast(_Tp __x) noexcept {
137145 return std::__saturate_cast<_Rp>(__x);
138146}
139147
lib/libcxx/include/__ostream/basic_ostream.h+8-8
......@@ -53,7 +53,7 @@ public:
5353 typedef typename traits_type::off_type off_type;
5454
5555 // 27.7.2.2 Constructor/destructor:
56 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb) {
56 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb) {
5757 this->init(__sb);
5858 }
5959 ~basic_ostream() override;
......@@ -67,7 +67,7 @@ protected:
6767 // 27.7.2.3 Assign/swap
6868 inline _LIBCPP_HIDE_FROM_ABI basic_ostream& operator=(basic_ostream&& __rhs);
6969
70 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void swap(basic_ostream& __rhs) {
70 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void swap(basic_ostream& __rhs) {
7171 basic_ios<char_type, traits_type>::swap(__rhs);
7272 }
7373
......@@ -76,17 +76,17 @@ public:
7676 class sentry;
7777
7878 // 27.7.2.6 Formatted output:
79 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&)) {
79 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&)) {
8080 return __pf(*this);
8181 }
8282
83 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream&
83 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_ostream&
8484 operator<<(basic_ios<char_type, traits_type>& (*__pf)(basic_ios<char_type, traits_type>&)) {
8585 __pf(*this);
8686 return *this;
8787 }
8888
89 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& operator<<(ios_base& (*__pf)(ios_base&)) {
89 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_ostream& operator<<(ios_base& (*__pf)(ios_base&)) {
9090 __pf(*this);
9191 return *this;
9292 }
......@@ -174,9 +174,9 @@ public:
174174 basic_ostream& flush();
175175
176176 // 27.7.2.5 seeks:
177 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type tellp();
178 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& seekp(pos_type __pos);
179 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& seekp(off_type __off, ios_base::seekdir __dir);
177 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 pos_type tellp();
178 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_ostream& seekp(pos_type __pos);
179 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_ostream& seekp(off_type __off, ios_base::seekdir __dir);
180180
181181protected:
182182 _LIBCPP_HIDE_FROM_ABI basic_ostream() {} // extension, intentially does not initialize
lib/libcxx/include/__pstl/backends/default.h+14-14
......@@ -102,7 +102,7 @@ struct __find<__default_backend_tag, _ExecutionPolicy> {
102102 operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) const noexcept {
103103 using _FindIf = __dispatch<__find_if, __current_configuration, _ExecutionPolicy>;
104104 return _FindIf()(
105 __policy, std::move(__first), std::move(__last), [&](__iter_reference<_ForwardIterator> __element) {
105 __policy, std::move(__first), std::move(__last), [&](__iterator_reference<_ForwardIterator> __element) {
106106 return __element == __value;
107107 });
108108 }
......@@ -137,7 +137,7 @@ struct __all_of<__default_backend_tag, _ExecutionPolicy> {
137137 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
138138 operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
139139 using _AnyOf = __dispatch<__any_of, __current_configuration, _ExecutionPolicy>;
140 auto __res = _AnyOf()(__policy, __first, __last, [&](__iter_reference<_ForwardIterator> __value) {
140 auto __res = _AnyOf()(__policy, __first, __last, [&](__iterator_reference<_ForwardIterator> __value) {
141141 return !__pred(__value);
142142 });
143143 if (!__res)
......@@ -204,7 +204,7 @@ struct __fill<__default_backend_tag, _ExecutionPolicy> {
204204 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
205205 operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __value) const noexcept {
206206 using _ForEach = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
207 using _Ref = __iter_reference<_ForwardIterator>;
207 using _Ref = __iterator_reference<_ForwardIterator>;
208208 return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) { __element = __value; });
209209 }
210210};
......@@ -233,7 +233,7 @@ struct __replace<__default_backend_tag, _ExecutionPolicy> {
233233 operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __old, _Tp const& __new)
234234 const noexcept {
235235 using _ReplaceIf = __dispatch<__replace_if, __current_configuration, _ExecutionPolicy>;
236 using _Ref = __iter_reference<_ForwardIterator>;
236 using _Ref = __iterator_reference<_ForwardIterator>;
237237 return _ReplaceIf()(
238238 __policy, std::move(__first), std::move(__last), [&](_Ref __element) { return __element == __old; }, __new);
239239 }
......@@ -246,7 +246,7 @@ struct __replace_if<__default_backend_tag, _ExecutionPolicy> {
246246 _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred, _Tp const& __new_value)
247247 const noexcept {
248248 using _ForEach = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
249 using _Ref = __iter_reference<_ForwardIterator>;
249 using _Ref = __iterator_reference<_ForwardIterator>;
250250 return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) {
251251 if (__pred(__element))
252252 __element = __new_value;
......@@ -260,7 +260,7 @@ struct __generate<__default_backend_tag, _ExecutionPolicy> {
260260 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
261261 operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator&& __gen) const noexcept {
262262 using _ForEach = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
263 using _Ref = __iter_reference<_ForwardIterator>;
263 using _Ref = __iterator_reference<_ForwardIterator>;
264264 return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) { __element = __gen(); });
265265 }
266266};
......@@ -271,7 +271,7 @@ struct __generate_n<__default_backend_tag, _ExecutionPolicy> {
271271 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
272272 operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, _Generator&& __gen) const noexcept {
273273 using _ForEachN = __dispatch<__for_each_n, __current_configuration, _ExecutionPolicy>;
274 using _Ref = __iter_reference<_ForwardIterator>;
274 using _Ref = __iterator_reference<_ForwardIterator>;
275275 return _ForEachN()(__policy, std::move(__first), __n, [&](_Ref __element) { __element = __gen(); });
276276 }
277277};
......@@ -295,11 +295,11 @@ struct __sort<__default_backend_tag, _ExecutionPolicy> {
295295template <class _ExecutionPolicy>
296296struct __count_if<__default_backend_tag, _ExecutionPolicy> {
297297 template <class _Policy, class _ForwardIterator, class _Predicate>
298 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>> operator()(
298 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iterator_difference_type<_ForwardIterator>> operator()(
299299 _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate&& __pred) const noexcept {
300300 using _TransformReduce = __dispatch<__transform_reduce, __current_configuration, _ExecutionPolicy>;
301 using _DiffT = __iter_diff_t<_ForwardIterator>;
302 using _Ref = __iter_reference<_ForwardIterator>;
301 using _DiffT = __iterator_difference_type<_ForwardIterator>;
302 using _Ref = __iterator_reference<_ForwardIterator>;
303303 return _TransformReduce()(
304304 __policy, std::move(__first), std::move(__last), _DiffT{}, std::plus{}, [&](_Ref __element) -> _DiffT {
305305 return __pred(__element) ? _DiffT(1) : _DiffT(0);
......@@ -310,10 +310,10 @@ struct __count_if<__default_backend_tag, _ExecutionPolicy> {
310310template <class _ExecutionPolicy>
311311struct __count<__default_backend_tag, _ExecutionPolicy> {
312312 template <class _Policy, class _ForwardIterator, class _Tp>
313 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>>
313 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iterator_difference_type<_ForwardIterator>>
314314 operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __value) const noexcept {
315315 using _CountIf = __dispatch<__count_if, __current_configuration, _ExecutionPolicy>;
316 using _Ref = __iter_reference<_ForwardIterator>;
316 using _Ref = __iterator_reference<_ForwardIterator>;
317317 return _CountIf()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) -> bool {
318318 return __element == __value;
319319 });
......@@ -402,7 +402,7 @@ struct __replace_copy_if<__default_backend_tag, _ExecutionPolicy> {
402402 _Pred&& __pred,
403403 _Tp const& __new_value) const noexcept {
404404 using _Transform = __dispatch<__transform, __current_configuration, _ExecutionPolicy>;
405 using _Ref = __iter_reference<_ForwardIterator>;
405 using _Ref = __iterator_reference<_ForwardIterator>;
406406 auto __res =
407407 _Transform()(__policy, std::move(__first), std::move(__last), std::move(__out_it), [&](_Ref __element) {
408408 return __pred(__element) ? __new_value : __element;
......@@ -424,7 +424,7 @@ struct __replace_copy<__default_backend_tag, _ExecutionPolicy> {
424424 _Tp const& __old_value,
425425 _Tp const& __new_value) const noexcept {
426426 using _ReplaceCopyIf = __dispatch<__replace_copy_if, __current_configuration, _ExecutionPolicy>;
427 using _Ref = __iter_reference<_ForwardIterator>;
427 using _Ref = __iterator_reference<_ForwardIterator>;
428428 return _ReplaceCopyIf()(
429429 __policy,
430430 std::move(__first),
lib/libcxx/include/__pstl/backends/libdispatch.h+2-2
......@@ -269,7 +269,7 @@ struct __cpu_traits<__libdispatch_backend_tag> {
269269 return __empty{};
270270 }
271271
272 using _Value = __iter_value_type<_RandomAccessIterator>;
272 using _Value = __iterator_value_type<_RandomAccessIterator>;
273273
274274 auto __destroy = [__size](_Value* __ptr) {
275275 std::destroy_n(__ptr, __size);
......@@ -282,7 +282,7 @@ struct __cpu_traits<__libdispatch_backend_tag> {
282282 // Initialize all elements to a moved-from state
283283 // TODO: Don't do this - this can be done in the first merge - see https://llvm.org/PR63928
284284 std::__construct_at(__values.get(), std::move(*__first));
285 for (__iter_diff_t<_RandomAccessIterator> __i = 1; __i != __size; ++__i) {
285 for (__iterator_difference_type<_RandomAccessIterator> __i = 1; __i != __size; ++__i) {
286286 std::__construct_at(__values.get() + __i, std::move(__values.get()[__i - 1]));
287287 }
288288 *__first = std::move(__values.get()[__size - 1]);
lib/libcxx/include/__pstl/cpu_algos/find_if.h+1-1
......@@ -119,7 +119,7 @@ struct __cpu_parallel_find_if {
119119 true);
120120 } else if constexpr (__is_unsequenced_execution_policy_v<_RawExecutionPolicy> &&
121121 __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
122 using __diff_t = __iter_diff_t<_ForwardIterator>;
122 using __diff_t = __iterator_difference_type<_ForwardIterator>;
123123 return __pstl::__simd_first<_Backend>(
124124 __first, __diff_t(0), __last - __first, [&__pred](_ForwardIterator __iter, __diff_t __i) {
125125 return __pred(__iter[__i]);
lib/libcxx/include/__pstl/cpu_algos/transform.h+5-6
......@@ -84,9 +84,8 @@ struct __cpu_parallel_transform {
8484 __first,
8585 __last - __first,
8686 __result,
87 [&](__iter_reference<_ForwardIterator> __in_value, __iter_reference<_ForwardOutIterator> __out_value) {
88 __out_value = __op(__in_value);
89 });
87 [&](__iterator_reference<_ForwardIterator> __in_value,
88 __iterator_reference<_ForwardOutIterator> __out_value) { __out_value = __op(__in_value); });
9089 } else {
9190 return std::transform(__first, __last, __result, __op);
9291 }
......@@ -138,9 +137,9 @@ struct __cpu_parallel_transform_binary {
138137 __last1 - __first1,
139138 __first2,
140139 __result,
141 [&](__iter_reference<_ForwardIterator1> __in1,
142 __iter_reference<_ForwardIterator2> __in2,
143 __iter_reference<_ForwardOutIterator> __out_value) { __out_value = __op(__in1, __in2); });
140 [&](__iterator_reference<_ForwardIterator1> __in1,
141 __iterator_reference<_ForwardIterator2> __in2,
142 __iterator_reference<_ForwardOutIterator> __out_value) { __out_value = __op(__in1, __in2); });
144143 } else {
145144 return std::transform(__first1, __last1, __first2, __result, __op);
146145 }
lib/libcxx/include/__pstl/cpu_algos/transform_reduce.h+5-4
......@@ -148,9 +148,10 @@ struct __cpu_parallel_transform_reduce_binary {
148148 __has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
149149 __has_random_access_iterator_category_or_concept<_ForwardIterator2>::value) {
150150 return __pstl::__simd_transform_reduce<_Backend>(
151 __last1 - __first1, std::move(__init), std::move(__reduce), [&](__iter_diff_t<_ForwardIterator1> __i) {
152 return __transform(__first1[__i], __first2[__i]);
153 });
151 __last1 - __first1,
152 std::move(__init),
153 std::move(__reduce),
154 [&](__iterator_difference_type<_ForwardIterator1> __i) { return __transform(__first1[__i], __first2[__i]); });
154155 } else {
155156 return std::transform_reduce(
156157 std::move(__first1),
......@@ -200,7 +201,7 @@ struct __cpu_parallel_transform_reduce {
200201 __last - __first,
201202 std::move(__init),
202203 std::move(__reduce),
203 [=, &__transform](__iter_diff_t<_ForwardIterator> __i) { return __transform(__first[__i]); });
204 [=, &__transform](__iterator_difference_type<_ForwardIterator> __i) { return __transform(__first[__i]); });
204205 } else {
205206 return std::transform_reduce(
206207 std::move(__first), std::move(__last), std::move(__init), std::move(__reduce), std::move(__transform));
lib/libcxx/include/__random/binomial_distribution.h+10-4
......@@ -97,13 +97,19 @@ public:
9797 }
9898};
9999
100// The LLVM C library provides this with conflicting `noexcept` attributes.
101#if !defined(_LIBCPP_MSVCRT_LIKE) && !defined(__LLVM_LIBC__)
102extern "C" double lgamma_r(double, int*);
100// Some libc declares the math functions to be `noexcept`.
101#if _LIBCPP_GLIBC_PREREQ(2, 8) || defined(__LLVM_LIBC__)
102# define _LIBCPP_LGAMMA_R_NOEXCEPT _NOEXCEPT
103#else
104# define _LIBCPP_LGAMMA_R_NOEXCEPT
105#endif
106
107#if !defined(_LIBCPP_MSVCRT_LIKE)
108extern "C" double lgamma_r(double, int*) _LIBCPP_LGAMMA_R_NOEXCEPT;
103109#endif
104110
105111inline _LIBCPP_HIDE_FROM_ABI double __libcpp_lgamma(double __d) {
106#if defined(_LIBCPP_MSVCRT_LIKE) || defined(__LLVM_LIBC__)
112#if defined(_LIBCPP_MSVCRT_LIKE)
107113 return lgamma(__d);
108114#else
109115 int __sign;
lib/libcxx/include/__random/mersenne_twister_engine.h+50-154
......@@ -62,24 +62,6 @@ _LIBCPP_HIDE_FROM_ABI bool
6262operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
6363 const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
6464
65template <class _UInt,
66 size_t _Wp,
67 size_t _Np,
68 size_t _Mp,
69 size_t _Rp,
70 _UInt _Ap,
71 size_t _Up,
72 _UInt _Dp,
73 size_t _Sp,
74 _UInt _Bp,
75 size_t _Tp,
76 _UInt _Cp,
77 size_t _Lp,
78 _UInt _Fp>
79_LIBCPP_HIDE_FROM_ABI bool
80operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
81 const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
82
8365template <class _CharT,
8466 class _Traits,
8567 class _UInt,
......@@ -194,14 +176,31 @@ public:
194176 _LIBCPP_HIDE_FROM_ABI explicit mersenne_twister_engine(_Sseq& __q) {
195177 seed(__q);
196178 }
197 _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd = default_seed);
179 _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd = default_seed) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK {
180 __x_[0] = __sd & _Max;
181 for (size_t __i = 1; __i < __n; ++__i)
182 __x_[__i] = (__f * (__x_[__i - 1] ^ __rshift<__w - 2>(__x_[__i - 1])) + __i) & _Max;
183 __i_ = 0;
184 }
198185 template <class _Sseq, __enable_if_t<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value, int> = 0>
199186 _LIBCPP_HIDE_FROM_ABI void seed(_Sseq& __q) {
200187 __seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());
201188 }
202189
203190 // generating functions
204 _LIBCPP_HIDE_FROM_ABI result_type operator()();
191 _LIBCPP_HIDE_FROM_ABI result_type operator()() {
192 const size_t __j = (__i_ + 1) % __n;
193 const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
194 const result_type __yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask);
195 const size_t __k = (__i_ + __m) % __n;
196 __x_[__i_] = __x_[__k] ^ __rshift<1>(__yp) ^ (__a * (__yp & 1));
197 result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d);
198 __i_ = __j;
199 __z ^= __lshift<__s>(__z) & __b;
200 __z ^= __lshift<__t>(__z) & __c;
201 return __z ^ __rshift<__l>(__z);
202 }
203
205204 _LIBCPP_HIDE_FROM_ABI void discard(unsigned long long __z) {
206205 for (; __z; --__z)
207206 operator()();
......@@ -225,24 +224,6 @@ public:
225224 const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
226225 const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
227226
228 template <class _UInt,
229 size_t _Wp,
230 size_t _Np,
231 size_t _Mp,
232 size_t _Rp,
233 _UInt _Ap,
234 size_t _Up,
235 _UInt _Dp,
236 size_t _Sp,
237 _UInt _Bp,
238 size_t _Tp,
239 _UInt _Cp,
240 size_t _Lp,
241 _UInt _Fp>
242 friend bool operator!=(
243 const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
244 const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
245
246227 template <class _CharT,
247228 class _Traits,
248229 class _UInt,
......@@ -285,9 +266,38 @@ public:
285266
286267private:
287268 template <class _Sseq>
288 _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
269 _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>) {
270 const unsigned __k = 1;
271 uint32_t __ar[__n * __k];
272 __q.generate(__ar, __ar + __n * __k);
273 for (size_t __i = 0; __i < __n; ++__i)
274 __x_[__i] = static_cast<result_type>(__ar[__i] & _Max);
275 const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
276 __i_ = 0;
277 if ((__x_[0] & ~__mask) == 0) {
278 for (size_t __i = 1; __i < __n; ++__i)
279 if (__x_[__i] != 0)
280 return;
281 __x_[0] = result_type(1) << (__w - 1);
282 }
283 }
284
289285 template <class _Sseq>
290 _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
286 _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>) {
287 const unsigned __k = 2;
288 uint32_t __ar[__n * __k];
289 __q.generate(__ar, __ar + __n * __k);
290 for (size_t __i = 0; __i < __n; ++__i)
291 __x_[__i] = static_cast<result_type>((__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max);
292 const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
293 __i_ = 0;
294 if ((__x_[0] & ~__mask) == 0) {
295 for (size_t __i = 1; __i < __n; ++__i)
296 if (__x_[__i] != 0)
297 return;
298 __x_[0] = result_type(1) << (__w - 1);
299 }
300 }
291301
292302 template <size_t __count,
293303 __enable_if_t<__count< __w, int> = 0> _LIBCPP_HIDE_FROM_ABI static result_type __lshift(result_type __x) {
......@@ -310,120 +320,6 @@ private:
310320 }
311321};
312322
313template <class _UIntType,
314 size_t __w,
315 size_t __n,
316 size_t __m,
317 size_t __r,
318 _UIntType __a,
319 size_t __u,
320 _UIntType __d,
321 size_t __s,
322 _UIntType __b,
323 size_t __t,
324 _UIntType __c,
325 size_t __l,
326 _UIntType __f>
327void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::seed(
328 result_type __sd) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { // __w >= 2
329 __x_[0] = __sd & _Max;
330 for (size_t __i = 1; __i < __n; ++__i)
331 __x_[__i] = (__f * (__x_[__i - 1] ^ __rshift<__w - 2>(__x_[__i - 1])) + __i) & _Max;
332 __i_ = 0;
333}
334
335template <class _UIntType,
336 size_t __w,
337 size_t __n,
338 size_t __m,
339 size_t __r,
340 _UIntType __a,
341 size_t __u,
342 _UIntType __d,
343 size_t __s,
344 _UIntType __b,
345 size_t __t,
346 _UIntType __c,
347 size_t __l,
348 _UIntType __f>
349template <class _Sseq>
350void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::__seed(
351 _Sseq& __q, integral_constant<unsigned, 1>) {
352 const unsigned __k = 1;
353 uint32_t __ar[__n * __k];
354 __q.generate(__ar, __ar + __n * __k);
355 for (size_t __i = 0; __i < __n; ++__i)
356 __x_[__i] = static_cast<result_type>(__ar[__i] & _Max);
357 const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
358 __i_ = 0;
359 if ((__x_[0] & ~__mask) == 0) {
360 for (size_t __i = 1; __i < __n; ++__i)
361 if (__x_[__i] != 0)
362 return;
363 __x_[0] = result_type(1) << (__w - 1);
364 }
365}
366
367template <class _UIntType,
368 size_t __w,
369 size_t __n,
370 size_t __m,
371 size_t __r,
372 _UIntType __a,
373 size_t __u,
374 _UIntType __d,
375 size_t __s,
376 _UIntType __b,
377 size_t __t,
378 _UIntType __c,
379 size_t __l,
380 _UIntType __f>
381template <class _Sseq>
382void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::__seed(
383 _Sseq& __q, integral_constant<unsigned, 2>) {
384 const unsigned __k = 2;
385 uint32_t __ar[__n * __k];
386 __q.generate(__ar, __ar + __n * __k);
387 for (size_t __i = 0; __i < __n; ++__i)
388 __x_[__i] = static_cast<result_type>((__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max);
389 const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
390 __i_ = 0;
391 if ((__x_[0] & ~__mask) == 0) {
392 for (size_t __i = 1; __i < __n; ++__i)
393 if (__x_[__i] != 0)
394 return;
395 __x_[0] = result_type(1) << (__w - 1);
396 }
397}
398
399template <class _UIntType,
400 size_t __w,
401 size_t __n,
402 size_t __m,
403 size_t __r,
404 _UIntType __a,
405 size_t __u,
406 _UIntType __d,
407 size_t __s,
408 _UIntType __b,
409 size_t __t,
410 _UIntType __c,
411 size_t __l,
412 _UIntType __f>
413_UIntType
414mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::operator()() {
415 const size_t __j = (__i_ + 1) % __n;
416 const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
417 const result_type __yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask);
418 const size_t __k = (__i_ + __m) % __n;
419 __x_[__i_] = __x_[__k] ^ __rshift<1>(__yp) ^ (__a * (__yp & 1));
420 result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d);
421 __i_ = __j;
422 __z ^= __lshift<__s>(__z) & __b;
423 __z ^= __lshift<__t>(__z) & __c;
424 return __z ^ __rshift<__l>(__z);
425}
426
427323template <class _UInt,
428324 size_t _Wp,
429325 size_t _Np,
lib/libcxx/include/__random/piecewise_constant_distribution.h+3-2
......@@ -9,9 +9,11 @@
99#ifndef _LIBCPP___RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_H
1010#define _LIBCPP___RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_H
1111
12#include <__algorithm/copy_n.h>
1213#include <__algorithm/upper_bound.h>
1314#include <__config>
1415#include <__cstddef/ptrdiff_t.h>
16#include <__iterator/back_insert_iterator.h>
1517#include <__random/is_valid.h>
1618#include <__random/uniform_real_distribution.h>
1719#include <__vector/vector.h>
......@@ -190,8 +192,7 @@ piecewise_constant_distribution<_RealType>::param_type::param_type(
190192 __areas_.assign(1, 0.0);
191193 } else {
192194 __densities_.reserve(__b_.size() - 1);
193 for (size_t __i = 0; __i < __b_.size() - 1; ++__i, ++__f_w)
194 __densities_.push_back(*__f_w);
195 std::copy_n(__f_w, __b_.size() - 1, std::back_inserter(__densities_));
195196 __init();
196197 }
197198}
lib/libcxx/include/__random/piecewise_linear_distribution.h+3-2
......@@ -9,9 +9,11 @@
99#ifndef _LIBCPP___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H
1010#define _LIBCPP___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H
1111
12#include <__algorithm/copy_n.h>
1213#include <__algorithm/upper_bound.h>
1314#include <__config>
1415#include <__cstddef/ptrdiff_t.h>
16#include <__iterator/back_insert_iterator.h>
1517#include <__random/is_valid.h>
1618#include <__random/uniform_real_distribution.h>
1719#include <__vector/comparison.h>
......@@ -194,8 +196,7 @@ piecewise_linear_distribution<_RealType>::param_type::param_type(
194196 __areas_.assign(1, 0.0);
195197 } else {
196198 __densities_.reserve(__b_.size());
197 for (size_t __i = 0; __i < __b_.size(); ++__i, ++__f_w)
198 __densities_.push_back(*__f_w);
199 std::copy_n(__f_w, __b_.size(), std::back_inserter(__densities_));
199200 __init();
200201 }
201202}
lib/libcxx/include/__ranges/adjacent_transform_view.h created+406
......@@ -0,0 +1,406 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_ADJACENT_TRANSFORM_VIEW_H
11#define _LIBCPP___RANGES_ADJACENT_TRANSFORM_VIEW_H
12
13#include <__config>
14
15#include <__algorithm/min.h>
16#include <__compare/three_way_comparable.h>
17#include <__concepts/constructible.h>
18#include <__concepts/convertible_to.h>
19#include <__concepts/derived_from.h>
20#include <__concepts/equality_comparable.h>
21#include <__concepts/invocable.h>
22#include <__cstddef/size_t.h>
23#include <__functional/bind_back.h>
24#include <__functional/invoke.h>
25#include <__functional/operations.h>
26#include <__iterator/concepts.h>
27#include <__iterator/incrementable_traits.h>
28#include <__iterator/iter_move.h>
29#include <__iterator/iter_swap.h>
30#include <__iterator/iterator_traits.h>
31#include <__iterator/next.h>
32#include <__iterator/prev.h>
33#include <__memory/addressof.h>
34#include <__ranges/access.h>
35#include <__ranges/adjacent_view.h>
36#include <__ranges/all.h>
37#include <__ranges/concepts.h>
38#include <__ranges/empty_view.h>
39#include <__ranges/movable_box.h>
40#include <__ranges/range_adaptor.h>
41#include <__ranges/size.h>
42#include <__ranges/view_interface.h>
43#include <__ranges/zip_transform_view.h>
44#include <__type_traits/common_type.h>
45#include <__type_traits/decay.h>
46#include <__type_traits/is_nothrow_constructible.h>
47#include <__type_traits/is_object.h>
48#include <__type_traits/is_referenceable.h>
49#include <__type_traits/make_unsigned.h>
50#include <__type_traits/maybe_const.h>
51#include <__utility/declval.h>
52#include <__utility/forward.h>
53#include <__utility/in_place.h>
54#include <__utility/integer_sequence.h>
55#include <__utility/move.h>
56
57#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
58# pragma GCC system_header
59#endif
60
61_LIBCPP_PUSH_MACROS
62#include <__undef_macros>
63
64_LIBCPP_BEGIN_NAMESPACE_STD
65
66#if _LIBCPP_STD_VER >= 23
67
68namespace ranges {
69
70template <class _Fn, size_t _Np>
71struct __apply_n {
72 template <class _Tp, size_t... _Is>
73 static auto __apply(index_sequence<_Is...>) -> invoke_result_t<_Fn, decltype((void)_Is, std::declval<_Tp>())...>;
74
75 template <class _Tp>
76 static auto operator()(_Tp&&) -> decltype(__apply<_Tp>(make_index_sequence<_Np>{}));
77};
78
79template <forward_range _View, move_constructible _Fn, size_t _Np>
80 requires view<_View> && (_Np > 0) && is_object_v<_Fn> &&
81 regular_invocable<__apply_n<_Fn&, _Np>, range_reference_t<_View>> &&
82 __referenceable<invoke_result_t<__apply_n<_Fn&, _Np>, range_reference_t<_View>>>
83class adjacent_transform_view : public view_interface<adjacent_transform_view<_View, _Fn, _Np>> {
84private:
85 _LIBCPP_NO_UNIQUE_ADDRESS adjacent_view<_View, _Np> __inner_;
86 _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Fn> __fun_;
87
88 using _InnerView _LIBCPP_NODEBUG = adjacent_view<_View, _Np>;
89
90 template <bool _Const>
91 using __inner_iterator _LIBCPP_NODEBUG = iterator_t<__maybe_const<_Const, _InnerView>>;
92
93 template <bool _Const>
94 using __inner_sentinel _LIBCPP_NODEBUG = sentinel_t<__maybe_const<_Const, _InnerView>>;
95
96 template <bool>
97 class __iterator;
98
99 template <bool>
100 class __sentinel;
101
102public:
103 _LIBCPP_HIDE_FROM_ABI adjacent_transform_view() = default;
104
105 _LIBCPP_HIDE_FROM_ABI constexpr explicit adjacent_transform_view(_View __base, _Fn __fun)
106 : __inner_(std::move(__base)), __fun_(std::in_place, std::move(__fun)) {}
107
108 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
109 requires copy_constructible<_View>
110 {
111 return __inner_.base();
112 }
113 _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__inner_).base(); }
114
115 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() { return __iterator<false>(*this, __inner_.begin()); }
116
117 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
118 requires range<const _InnerView> && regular_invocable<__apply_n<const _Fn&, _Np>, range_reference_t<const _View>>
119 {
120 return __iterator<true>(*this, __inner_.begin());
121 }
122
123 _LIBCPP_HIDE_FROM_ABI constexpr auto end() {
124 if constexpr (common_range<_InnerView>) {
125 return __iterator<false>(*this, __inner_.end());
126 } else {
127 return __sentinel<false>(__inner_.end());
128 }
129 }
130
131 _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
132 requires range<const _InnerView> && regular_invocable<__apply_n<const _Fn&, _Np>, range_reference_t<const _View>>
133 {
134 if constexpr (common_range<const _InnerView>) {
135 return __iterator<true>(*this, __inner_.end());
136 } else {
137 return __sentinel<true>(__inner_.end());
138 }
139 }
140
141 _LIBCPP_HIDE_FROM_ABI constexpr auto size()
142 requires sized_range<_InnerView>
143 {
144 return __inner_.size();
145 }
146
147 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
148 requires sized_range<const _InnerView>
149 {
150 return __inner_.size();
151 }
152};
153
154template <forward_range _View, move_constructible _Fn, size_t _Np>
155 requires view<_View> && (_Np > 0) && is_object_v<_Fn> &&
156 regular_invocable<__apply_n<_Fn&, _Np>, range_reference_t<_View>> &&
157 __referenceable<invoke_result_t<__apply_n<_Fn&, _Np>, range_reference_t<_View>>>
158template <bool _Const>
159class adjacent_transform_view<_View, _Fn, _Np>::__iterator {
160 friend adjacent_transform_view;
161
162 using _Parent _LIBCPP_NODEBUG = __maybe_const<_Const, adjacent_transform_view>;
163 using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>;
164
165 _Parent* __parent_ = nullptr;
166 __inner_iterator<_Const> __inner_;
167
168 _LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent& __parent, __inner_iterator<_Const> __inner)
169 : __parent_(std::addressof(__parent)), __inner_(std::move(__inner)) {}
170
171 static consteval auto __get_iterator_category() {
172 using _Cat = iterator_traits<iterator_t<_Base>>::iterator_category;
173 if constexpr (!is_reference_v<
174 invoke_result_t<__apply_n<__maybe_const<_Const, _Fn>&, _Np>, range_reference_t<_Base>>>)
175 return input_iterator_tag{};
176 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
177 return random_access_iterator_tag{};
178 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
179 return bidirectional_iterator_tag{};
180 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
181 return forward_iterator_tag{};
182 else
183 return input_iterator_tag{};
184 }
185
186 template <size_t... _Is>
187 static consteval bool __noexcept_dereference(index_sequence<_Is...>) {
188 return noexcept(std::invoke(
189 std::declval<__maybe_const<_Const, _Fn>&>(), ((void)_Is, *std::declval<iterator_t<_Base> const&>())...));
190 }
191
192public:
193 using iterator_category = decltype(__get_iterator_category());
194 using iterator_concept = typename __inner_iterator<_Const>::iterator_concept;
195 using value_type =
196 remove_cvref_t<invoke_result_t<__apply_n<__maybe_const<_Const, _Fn>&, _Np>, range_reference_t<_Base>>>;
197 using difference_type = range_difference_t<_Base>;
198
199 _LIBCPP_HIDE_FROM_ABI __iterator() = default;
200
201 _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
202 requires _Const && convertible_to<__inner_iterator<false>, __inner_iterator<true>>
203 : __parent_(__i.__parent_), __inner_(std::move(__i.__inner_)) {}
204
205 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const
206 noexcept(__noexcept_dereference(make_index_sequence<_Np>{})) {
207 return std::apply(
208 [&](const auto&... __iters) -> decltype(auto) { return std::invoke(*__parent_->__fun_, *__iters...); },
209 __adjacent_view_iter_access::__get_current(__inner_));
210 }
211
212 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
213 ++__inner_;
214 return *this;
215 }
216
217 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) {
218 auto __tmp = *this;
219 ++*this;
220 return __tmp;
221 }
222
223 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
224 requires bidirectional_range<_Base>
225 {
226 --__inner_;
227 return *this;
228 }
229
230 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
231 requires bidirectional_range<_Base>
232 {
233 auto __tmp = *this;
234 --*this;
235 return __tmp;
236 }
237
238 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __x)
239 requires random_access_range<_Base>
240 {
241 __inner_ += __x;
242 return *this;
243 }
244
245 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __x)
246 requires random_access_range<_Base>
247 {
248 __inner_ -= __x;
249 return *this;
250 }
251
252 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const
253 requires random_access_range<_Base>
254 {
255 return std::apply(
256 [&](const auto&... __iters) -> decltype(auto) { return std::invoke(*__parent_->__fun_, __iters[__n]...); },
257 __adjacent_view_iter_access::__get_current(__inner_));
258 }
259
260 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
261 return __x.__inner_ == __y.__inner_;
262 }
263
264 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
265 requires random_access_range<_Base>
266 {
267 return __x.__inner_ < __y.__inner_;
268 }
269
270 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
271 requires random_access_range<_Base>
272 {
273 return __x.__inner_ > __y.__inner_;
274 }
275
276 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
277 requires random_access_range<_Base>
278 {
279 return __x.__inner_ <= __y.__inner_;
280 }
281
282 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
283 requires random_access_range<_Base>
284 {
285 return __x.__inner_ >= __y.__inner_;
286 }
287
288 _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
289 requires random_access_range<_Base> && three_way_comparable<__inner_iterator<_Const>>
290 {
291 return __x.__inner_ <=> __y.__inner_;
292 }
293
294 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __i, difference_type __n)
295 requires random_access_range<_Base>
296 {
297 return __iterator(*__i.__parent_, __i.__inner_ + __n);
298 }
299
300 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, const __iterator& __i)
301 requires random_access_range<_Base>
302 {
303 return __iterator(*__i.__parent_, __i.__inner_ + __n);
304 }
305
306 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __i, difference_type __n)
307 requires random_access_range<_Base>
308 {
309 return __iterator(*__i.__parent_, __i.__inner_ - __n);
310 }
311
312 _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
313 requires sized_sentinel_for<__inner_iterator<_Const>, __inner_iterator<_Const>>
314 {
315 return __x.__inner_ - __y.__inner_;
316 }
317};
318
319template <forward_range _View, move_constructible _Fn, size_t _Np>
320 requires view<_View> && (_Np > 0) && is_object_v<_Fn> &&
321 regular_invocable<__apply_n<_Fn&, _Np>, range_reference_t<_View>> &&
322 __referenceable<invoke_result_t<__apply_n<_Fn&, _Np>, range_reference_t<_View>>>
323template <bool _Const>
324class adjacent_transform_view<_View, _Fn, _Np>::__sentinel {
325 friend adjacent_transform_view;
326
327 __inner_sentinel<_Const> __inner_;
328
329 _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(__inner_sentinel<_Const> __inner)
330 : __inner_(std::move(__inner)) {}
331
332public:
333 _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
334
335 _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __i)
336 requires _Const && convertible_to<__inner_sentinel<false>, __inner_sentinel<_Const>>
337 : __inner_(std::move(__i.__inner_)) {}
338
339 template <bool _OtherConst>
340 requires sentinel_for<__inner_sentinel<_Const>, __inner_iterator<_OtherConst>>
341 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
342 return __x.__inner_ == __y.__inner_;
343 }
344
345 template <bool _OtherConst>
346 requires sized_sentinel_for<__inner_sentinel<_Const>, __inner_iterator<_OtherConst>>
347 _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _InnerView>>
348 operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
349 return __x.__inner_ - __y.__inner_;
350 }
351
352 template <bool _OtherConst>
353 requires sized_sentinel_for<__inner_sentinel<_Const>, __inner_iterator<_OtherConst>>
354 _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _InnerView>>
355 operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) {
356 return __x.__inner_ - __y.__inner_;
357 }
358};
359
360namespace views {
361namespace __adjacent_transform {
362
363template <size_t _Np>
364struct __fn : __range_adaptor_closure<__fn<_Np>> {
365 template <class _Range, class _Fn>
366 requires(_Np == 0 && forward_range<_Range &&>)
367 _LIBCPP_HIDE_FROM_ABI static constexpr auto
368 operator()(_Range&&, _Fn&& __fn) noexcept(noexcept(views::zip_transform(std::forward<_Fn>(__fn))))
369 -> decltype(views::zip_transform(std::forward<_Fn>(__fn))) {
370 return views::zip_transform(std::forward<_Fn>(__fn));
371 }
372
373 template <class _Range, class _Fn>
374 _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range, _Fn&& __fn) noexcept(
375 noexcept(adjacent_transform_view<views::all_t<_Range&&>, decay_t<_Fn>, _Np>(
376 std::forward<_Range>(__range), std::forward<_Fn>(__fn))))
377 -> decltype(adjacent_transform_view<views::all_t<_Range&&>, decay_t<_Fn>, _Np>(
378 std::forward<_Range>(__range), std::forward<_Fn>(__fn))) {
379 return adjacent_transform_view<views::all_t<_Range&&>, decay_t<_Fn>, _Np>(
380 std::forward<_Range>(__range), std::forward<_Fn>(__fn));
381 }
382
383 template <class _Fn>
384 requires constructible_from<decay_t<_Fn>, _Fn>
385 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Fn&& __f) const
386 noexcept(is_nothrow_constructible_v<decay_t<_Fn>, _Fn>) {
387 return __pipeable(std::__bind_back(*this, std::forward<_Fn>(__f)));
388 }
389};
390
391} // namespace __adjacent_transform
392inline namespace __cpo {
393template <size_t _Np>
394inline constexpr auto adjacent_transform = __adjacent_transform::__fn<_Np>{};
395inline constexpr auto pairwise_transform = adjacent_transform<2>;
396} // namespace __cpo
397} // namespace views
398} // namespace ranges
399
400#endif // _LIBCPP_STD_VER >= 23
401
402_LIBCPP_END_NAMESPACE_STD
403
404_LIBCPP_POP_MACROS
405
406#endif // _LIBCPP___RANGES_ADJACENT_TRANSFORM_VIEW_H
lib/libcxx/include/__ranges/adjacent_view.h created+419
......@@ -0,0 +1,419 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_ADJACENT_VIEW_H
11#define _LIBCPP___RANGES_ADJACENT_VIEW_H
12
13#include <__config>
14
15#include <__algorithm/min.h>
16#include <__compare/three_way_comparable.h>
17#include <__concepts/constructible.h>
18#include <__concepts/convertible_to.h>
19#include <__concepts/equality_comparable.h>
20#include <__cstddef/size_t.h>
21#include <__functional/invoke.h>
22#include <__functional/operations.h>
23#include <__iterator/concepts.h>
24#include <__iterator/incrementable_traits.h>
25#include <__iterator/iter_move.h>
26#include <__iterator/iter_swap.h>
27#include <__iterator/iterator_traits.h>
28#include <__iterator/next.h>
29#include <__iterator/prev.h>
30#include <__ranges/access.h>
31#include <__ranges/all.h>
32#include <__ranges/concepts.h>
33#include <__ranges/empty_view.h>
34#include <__ranges/enable_borrowed_range.h>
35#include <__ranges/range_adaptor.h>
36#include <__ranges/size.h>
37#include <__ranges/view_interface.h>
38#include <__tuple/tuple_transform.h>
39#include <__type_traits/common_type.h>
40#include <__type_traits/is_nothrow_constructible.h>
41#include <__type_traits/make_unsigned.h>
42#include <__type_traits/maybe_const.h>
43#include <__utility/declval.h>
44#include <__utility/forward.h>
45#include <__utility/integer_sequence.h>
46#include <__utility/move.h>
47#include <array>
48#include <tuple>
49
50#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
51# pragma GCC system_header
52#endif
53
54_LIBCPP_PUSH_MACROS
55#include <__undef_macros>
56
57_LIBCPP_BEGIN_NAMESPACE_STD
58
59#if _LIBCPP_STD_VER >= 23
60
61namespace ranges {
62
63template <forward_range _View, size_t _Np>
64 requires view<_View> && (_Np > 0)
65class adjacent_view : public view_interface<adjacent_view<_View, _Np>> {
66private:
67 _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
68
69 template <bool>
70 class __iterator;
71
72 template <bool>
73 class __sentinel;
74
75 struct __as_sentinel {};
76
77public:
78 _LIBCPP_HIDE_FROM_ABI adjacent_view()
79 requires default_initializable<_View>
80 = default;
81
82 _LIBCPP_HIDE_FROM_ABI constexpr explicit adjacent_view(_View __base) : __base_(std::move(__base)) {}
83
84 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
85 requires copy_constructible<_View>
86 {
87 return __base_;
88 }
89 _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
90
91 _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
92 requires(!__simple_view<_View>)
93 {
94 return __iterator<false>(ranges::begin(__base_), ranges::end(__base_));
95 }
96
97 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
98 requires range<const _View> // LWG4482 This is under-constrained.
99 {
100 return __iterator<true>(ranges::begin(__base_), ranges::end(__base_));
101 }
102
103 _LIBCPP_HIDE_FROM_ABI constexpr auto end()
104 requires(!__simple_view<_View>)
105 {
106 if constexpr (common_range<_View>) {
107 return __iterator<false>(__as_sentinel{}, ranges::begin(__base_), ranges::end(__base_));
108 } else {
109 return __sentinel<false>(ranges::end(__base_));
110 }
111 }
112
113 _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
114 requires range<const _View> // LWG4482 This is under-constrained.
115 {
116 if constexpr (common_range<const _View>) {
117 return __iterator<true>(__as_sentinel{}, ranges::begin(__base_), ranges::end(__base_));
118 } else {
119 return __sentinel<true>(ranges::end(__base_));
120 }
121 }
122
123 _LIBCPP_HIDE_FROM_ABI constexpr auto size()
124 requires sized_range<_View>
125 {
126 using _ST = decltype(ranges::size(__base_));
127 using _CT = common_type_t<_ST, size_t>;
128 auto __sz = static_cast<_CT>(ranges::size(__base_));
129 __sz -= std::min<_CT>(__sz, _Np - 1);
130 return static_cast<_ST>(__sz);
131 }
132
133 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
134 requires sized_range<const _View>
135 {
136 using _ST = decltype(ranges::size(__base_));
137 using _CT = common_type_t<_ST, size_t>;
138 auto __sz = static_cast<_CT>(ranges::size(__base_));
139 __sz -= std::min<_CT>(__sz, _Np - 1);
140 return static_cast<_ST>(__sz);
141 }
142};
143
144struct __adjacent_view_iter_access {
145 template <class _Iter>
146 _LIBCPP_HIDE_FROM_ABI constexpr static auto& __get_current(_Iter& __it) noexcept {
147 return __it.__current_;
148 }
149};
150
151template <forward_range _View, size_t _Np>
152 requires view<_View> && (_Np > 0)
153template <bool _Const>
154class adjacent_view<_View, _Np>::__iterator {
155 friend __adjacent_view_iter_access;
156 friend adjacent_view;
157 using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>;
158 array<iterator_t<_Base>, _Np> __current_ = array<iterator_t<_Base>, _Np>();
159
160 _LIBCPP_HIDE_FROM_ABI constexpr __iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last) {
161 __current_[0] = __first;
162 for (size_t __i = 1; __i < _Np; ++__i) {
163 __current_[__i] = ranges::next(__current_[__i - 1], 1, __last);
164 }
165 }
166
167 _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last) {
168 if constexpr (!bidirectional_range<_Base>) {
169 __current_.fill(__last);
170 } else {
171 __current_[_Np - 1] = __last;
172 for (int __i = static_cast<int>(_Np) - 2; __i >= 0; --__i) {
173 __current_[__i] = ranges::prev(__current_[__i + 1], 1, __first);
174 }
175 }
176 }
177
178 template <class _Iter, size_t... _Is>
179 _LIBCPP_HIDE_FROM_ABI explicit constexpr __iterator(_Iter&& __i, index_sequence<_Is...>)
180 : __current_{std::move(__i.__current_[_Is])...} {}
181
182 static consteval auto __get_iterator_concept() {
183 if constexpr (random_access_range<_Base>)
184 return random_access_iterator_tag{};
185 else if constexpr (bidirectional_range<_Base>)
186 return bidirectional_iterator_tag{};
187 else
188 return forward_iterator_tag{};
189 }
190
191 template <class _Tp, size_t _Index>
192 using __always _LIBCPP_NODEBUG = _Tp;
193
194 template <class _Tp, size_t... _Is>
195 static auto __repeat_tuple_helper(index_sequence<_Is...>) -> tuple<__always<_Tp, _Is>...>;
196
197public:
198 using iterator_category = input_iterator_tag;
199 using iterator_concept = decltype(__get_iterator_concept());
200 using value_type = decltype(__repeat_tuple_helper<range_value_t<_Base>>(make_index_sequence<_Np>{}));
201 using difference_type = range_difference_t<_Base>;
202
203 _LIBCPP_HIDE_FROM_ABI __iterator() = default;
204 _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
205 requires _Const && convertible_to<iterator_t<_View>, iterator_t<const _View>>
206 : __iterator(std::move(__i), make_index_sequence<_Np>{}) {}
207
208 _LIBCPP_HIDE_FROM_ABI constexpr auto operator*() const {
209 return std::__tuple_transform([](auto& __i) -> decltype(auto) { return *__i; }, __current_);
210 }
211
212 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
213 for (auto& __i : __current_) {
214 ++__i;
215 }
216 return *this;
217 }
218
219 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) {
220 auto __tmp = *this;
221 ++*this;
222 return __tmp;
223 }
224
225 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
226 requires bidirectional_range<_Base>
227 {
228 for (auto& __i : __current_) {
229 --__i;
230 }
231 return *this;
232 }
233
234 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
235 requires bidirectional_range<_Base>
236 {
237 auto __tmp = *this;
238 --*this;
239 return __tmp;
240 }
241
242 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __x)
243 requires random_access_range<_Base>
244 {
245 for (auto& __i : __current_) {
246 __i += __x;
247 }
248 return *this;
249 }
250
251 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __x)
252 requires random_access_range<_Base>
253 {
254 for (auto& __i : __current_) {
255 __i -= __x;
256 }
257 return *this;
258 }
259
260 _LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type __n) const
261 requires random_access_range<_Base>
262 {
263 return std::__tuple_transform([&](auto& __i) -> decltype(auto) { return __i[__n]; }, __current_);
264 }
265
266 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
267 return __x.__current_.back() == __y.__current_.back();
268 }
269
270 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
271 requires random_access_range<_Base>
272 {
273 return __x.__current_.back() < __y.__current_.back();
274 }
275
276 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
277 requires random_access_range<_Base>
278 {
279 return __y < __x;
280 }
281
282 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
283 requires random_access_range<_Base>
284 {
285 return !(__y < __x);
286 }
287
288 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
289 requires random_access_range<_Base>
290 {
291 return !(__x < __y);
292 }
293
294 _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
295 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
296 {
297 return __x.__current_.back() <=> __y.__current_.back();
298 }
299
300 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __i, difference_type __n)
301 requires random_access_range<_Base>
302 {
303 auto __r = __i;
304 __r += __n;
305 return __r;
306 }
307
308 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, const __iterator& __i)
309 requires random_access_range<_Base>
310 {
311 return __i + __n;
312 }
313
314 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __i, difference_type __n)
315 requires random_access_range<_Base>
316 {
317 auto __r = __i;
318 __r -= __n;
319 return __r;
320 }
321
322 _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
323 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
324 {
325 return __x.__current_.back() - __y.__current_.back();
326 }
327
328 _LIBCPP_HIDE_FROM_ABI friend constexpr auto iter_move(const __iterator& __i) noexcept(
329 noexcept(ranges::iter_move(std::declval<const iterator_t<_Base>&>())) &&
330 is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>) {
331 return std::__tuple_transform(ranges::iter_move, __i.__current_);
332 }
333
334 _LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const __iterator& __l, const __iterator& __r) noexcept(
335 noexcept(ranges::iter_swap(std::declval<iterator_t<_Base>>(), std::declval<iterator_t<_Base>>())))
336 requires indirectly_swappable<iterator_t<_Base>>
337 {
338 for (size_t __i = 0; __i < _Np; ++__i) {
339 ranges::iter_swap(__l.__current_[__i], __r.__current_[__i]);
340 }
341 }
342};
343
344template <forward_range _View, size_t _Np>
345 requires view<_View> && (_Np > 0)
346template <bool _Const>
347class adjacent_view<_View, _Np>::__sentinel {
348 friend adjacent_view;
349 using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>;
350 sentinel_t<_Base> __end_ = sentinel_t<_Base>();
351
352 _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) { __end_ = std::move(__end); }
353
354public:
355 _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
356
357 _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __i)
358 requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
359 : __end_(std::move(__i.__end_)) {}
360
361 template <bool _OtherConst>
362 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
363 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
364 return __x.__current_.back() == __y.__end_;
365 }
366
367 template <bool _OtherConst>
368 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
369 _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
370 operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
371 return __x.__current_.back() - __y.__end_;
372 }
373
374 template <bool _OtherConst>
375 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
376 _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
377 operator-(const __sentinel& __y, const __iterator<_OtherConst>& __x) {
378 return __y.__end_ - __x.__current_.back();
379 }
380};
381
382template <class _View, size_t _Np>
383constexpr bool enable_borrowed_range<adjacent_view<_View, _Np>> = enable_borrowed_range<_View>;
384
385namespace views {
386namespace __adjacent {
387
388template <size_t _Np>
389struct __fn : __range_adaptor_closure<__fn<_Np>> {
390 template <class _Range>
391 requires(_Np == 0 && forward_range<_Range &&>)
392 _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&&) noexcept {
393 return empty_view<tuple<>>{};
394 }
395
396 template <class _Ranges>
397 _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Ranges&& __range) noexcept(
398 noexcept(adjacent_view<views::all_t<_Ranges&&>, _Np>(std::forward<_Ranges>(__range))))
399 -> decltype(adjacent_view<views::all_t<_Ranges&&>, _Np>(std::forward<_Ranges>(__range))) {
400 return adjacent_view<views::all_t<_Ranges&&>, _Np>(std::forward<_Ranges>(__range));
401 }
402};
403
404} // namespace __adjacent
405inline namespace __cpo {
406template <size_t _Np>
407inline constexpr auto adjacent = __adjacent::__fn<_Np>{};
408inline constexpr auto pairwise = adjacent<2>;
409} // namespace __cpo
410} // namespace views
411} // namespace ranges
412
413#endif // _LIBCPP_STD_VER >= 23
414
415_LIBCPP_END_NAMESPACE_STD
416
417_LIBCPP_POP_MACROS
418
419#endif // _LIBCPP___RANGES_ADJACENT_VIEW_H
lib/libcxx/include/__ranges/as_rvalue_view.h+9-9
......@@ -48,27 +48,27 @@ public:
4848
4949 _LIBCPP_HIDE_FROM_ABI constexpr explicit as_rvalue_view(_View __base) : __base_(std::move(__base)) {}
5050
51 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
51 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
5252 requires copy_constructible<_View>
5353 {
5454 return __base_;
5555 }
5656
57 _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
57 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
5858
59 _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
59 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
6060 requires(!__simple_view<_View>)
6161 {
6262 return move_iterator(ranges::begin(__base_));
6363 }
6464
65 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
65 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
6666 requires range<const _View>
6767 {
6868 return move_iterator(ranges::begin(__base_));
6969 }
7070
71 _LIBCPP_HIDE_FROM_ABI constexpr auto end()
71 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end()
7272 requires(!__simple_view<_View>)
7373 {
7474 if constexpr (common_range<_View>) {
......@@ -78,7 +78,7 @@ public:
7878 }
7979 }
8080
81 _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
81 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
8282 requires range<const _View>
8383 {
8484 if constexpr (common_range<const _View>) {
......@@ -88,13 +88,13 @@ public:
8888 }
8989 }
9090
91 _LIBCPP_HIDE_FROM_ABI constexpr auto size()
91 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size()
9292 requires sized_range<_View>
9393 {
9494 return ranges::size(__base_);
9595 }
9696
97 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
97 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
9898 requires sized_range<const _View>
9999 {
100100 return ranges::size(__base_);
......@@ -117,7 +117,7 @@ struct __fn : __range_adaptor_closure<__fn> {
117117 return /*---------------------------------*/ as_rvalue_view(std::forward<_Range>(__range));
118118 }
119119
120 template <class _Range>
120 template <input_range _Range>
121121 requires same_as<range_rvalue_reference_t<_Range>, range_reference_t<_Range>>
122122 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto
123123 operator()(_Range&& __range) noexcept(noexcept(views::all(std::forward<_Range>(__range))))
lib/libcxx/include/__ranges/chunk_by_view.h+6-6
......@@ -100,17 +100,17 @@ public:
100100 _LIBCPP_HIDE_FROM_ABI constexpr explicit chunk_by_view(_View __base, _Pred __pred)
101101 : __base_(std::move(__base)), __pred_(in_place, std::move(__pred)) {}
102102
103 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
103 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
104104 requires copy_constructible<_View>
105105 {
106106 return __base_;
107107 }
108108
109 _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
109 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
110110
111 _LIBCPP_HIDE_FROM_ABI constexpr const _Pred& pred() const { return *__pred_; }
111 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Pred& pred() const { return *__pred_; }
112112
113 _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() {
113 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() {
114114 // Note: this duplicates a check in `optional` but provides a better error message.
115115 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
116116 __pred_.__has_value(), "Trying to call begin() on a chunk_by_view that does not have a valid predicate.");
......@@ -122,7 +122,7 @@ public:
122122 return {*this, std::move(__first), *__cached_begin_};
123123 }
124124
125 _LIBCPP_HIDE_FROM_ABI constexpr auto end() {
125 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() {
126126 if constexpr (common_range<_View>) {
127127 return __iterator{*this, ranges::end(__base_), ranges::end(__base_)};
128128 } else {
......@@ -155,7 +155,7 @@ public:
155155
156156 _LIBCPP_HIDE_FROM_ABI __iterator() = default;
157157
158 _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const {
158 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const {
159159 // If the iterator is at end, this would return an empty range which can be checked by the calling code and doesn't
160160 // necessarily lead to a bad access.
161161 _LIBCPP_ASSERT_PEDANTIC(__current_ != __next_, "Trying to dereference past-the-end chunk_by_view iterator.");
lib/libcxx/include/__ranges/common_view.h+7-7
......@@ -56,16 +56,16 @@ public:
5656 return __base_;
5757 }
5858
59 _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
59 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
6060
61 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
61 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
6262 if constexpr (random_access_range<_View> && sized_range<_View>)
6363 return ranges::begin(__base_);
6464 else
6565 return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::begin(__base_));
6666 }
6767
68 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
68 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
6969 requires range<const _View>
7070 {
7171 if constexpr (random_access_range<const _View> && sized_range<const _View>)
......@@ -74,14 +74,14 @@ public:
7474 return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::begin(__base_));
7575 }
7676
77 _LIBCPP_HIDE_FROM_ABI constexpr auto end() {
77 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() {
7878 if constexpr (random_access_range<_View> && sized_range<_View>)
7979 return ranges::begin(__base_) + ranges::size(__base_);
8080 else
8181 return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::end(__base_));
8282 }
8383
84 _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
84 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
8585 requires range<const _View>
8686 {
8787 if constexpr (random_access_range<const _View> && sized_range<const _View>)
......@@ -90,13 +90,13 @@ public:
9090 return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::end(__base_));
9191 }
9292
93 _LIBCPP_HIDE_FROM_ABI constexpr auto size()
93 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size()
9494 requires sized_range<_View>
9595 {
9696 return ranges::size(__base_);
9797 }
9898
99 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
99 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
100100 requires sized_range<const _View>
101101 {
102102 return ranges::size(__base_);
lib/libcxx/include/__ranges/drop_view.h+8-8
......@@ -80,14 +80,14 @@ public:
8080 _LIBCPP_ASSERT_UNCATEGORIZED(__count_ >= 0, "count must be greater than or equal to zero.");
8181 }
8282
83 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
83 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
8484 requires copy_constructible<_View>
8585 {
8686 return __base_;
8787 }
88 _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
88 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
8989
90 _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
90 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
9191 requires(!(__simple_view<_View> && random_access_range<const _View> && sized_range<const _View>))
9292 {
9393 if constexpr (random_access_range<_View> && sized_range<_View>) {
......@@ -104,20 +104,20 @@ public:
104104 return __tmp;
105105 }
106106
107 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
107 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
108108 requires random_access_range<const _View> && sized_range<const _View>
109109 {
110110 const auto __dist = std::min(ranges::distance(__base_), __count_);
111111 return ranges::begin(__base_) + __dist;
112112 }
113113
114 _LIBCPP_HIDE_FROM_ABI constexpr auto end()
114 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end()
115115 requires(!__simple_view<_View>)
116116 {
117117 return ranges::end(__base_);
118118 }
119119
120 _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
120 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
121121 requires range<const _View>
122122 {
123123 return ranges::end(__base_);
......@@ -129,13 +129,13 @@ public:
129129 return __s < __c ? 0 : __s - __c;
130130 }
131131
132 _LIBCPP_HIDE_FROM_ABI constexpr auto size()
132 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size()
133133 requires sized_range<_View>
134134 {
135135 return __size(*this);
136136 }
137137
138 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
138 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
139139 requires sized_range<const _View>
140140 {
141141 return __size(*this);
lib/libcxx/include/__ranges/drop_while_view.h+5-5
......@@ -57,17 +57,17 @@ public:
5757 _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 drop_while_view(_View __base, _Pred __pred)
5858 : __base_(std::move(__base)), __pred_(std::in_place, std::move(__pred)) {}
5959
60 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
60 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
6161 requires copy_constructible<_View>
6262 {
6363 return __base_;
6464 }
6565
66 _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
66 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
6767
68 _LIBCPP_HIDE_FROM_ABI constexpr const _Pred& pred() const { return *__pred_; }
68 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Pred& pred() const { return *__pred_; }
6969
70 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
70 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
7171 // Note: this duplicates a check in `optional` but provides a better error message.
7272 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
7373 __pred_.__has_value(),
......@@ -83,7 +83,7 @@ public:
8383 }
8484 }
8585
86 _LIBCPP_HIDE_FROM_ABI constexpr auto end() { return ranges::end(__base_); }
86 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() { return ranges::end(__base_); }
8787
8888private:
8989 _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
lib/libcxx/include/__ranges/elements_of.h created+49
......@@ -0,0 +1,49 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_ELEMENTS_OF_H
11#define _LIBCPP___RANGES_ELEMENTS_OF_H
12
13#include <__config>
14#include <__cstddef/byte.h>
15#include <__memory/allocator.h>
16#include <__ranges/concepts.h>
17#include <__utility/forward.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28#if _LIBCPP_STD_VER >= 23
29
30namespace ranges {
31
32template <range _Range, class _Allocator = allocator<byte>>
33struct elements_of {
34 _LIBCPP_NO_UNIQUE_ADDRESS _Range range;
35 _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator = _Allocator();
36};
37
38template <class _Range, class _Allocator = allocator<byte>>
39elements_of(_Range&&, _Allocator = _Allocator()) -> elements_of<_Range&&, _Allocator>;
40
41} // namespace ranges
42
43#endif // _LIBCPP_STD_VER >= 23
44
45_LIBCPP_END_NAMESPACE_STD
46
47_LIBCPP_POP_MACROS
48
49#endif // _LIBCPP___RANGES_ELEMENTS_OF_H
lib/libcxx/include/__ranges/empty_view.h+5-5
......@@ -29,11 +29,11 @@ template <class _Tp>
2929 requires is_object_v<_Tp>
3030class empty_view : public view_interface<empty_view<_Tp>> {
3131public:
32 _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* begin() noexcept { return nullptr; }
33 _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* end() noexcept { return nullptr; }
34 _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* data() noexcept { return nullptr; }
35 _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 0; }
36 _LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return true; }
32 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* begin() noexcept { return nullptr; }
33 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* end() noexcept { return nullptr; }
34 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* data() noexcept { return nullptr; }
35 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 0; }
36 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return true; }
3737};
3838
3939template <class _Tp>
lib/libcxx/include/__ranges/filter_view.h+10-10
......@@ -76,16 +76,16 @@ public:
7676 : __base_(std::move(__base)), __pred_(in_place, std::move(__pred)) {}
7777
7878 template <class _Vp = _View>
79 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
79 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
8080 requires copy_constructible<_Vp>
8181 {
8282 return __base_;
8383 }
84 _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
84 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
8585
86 _LIBCPP_HIDE_FROM_ABI constexpr _Pred const& pred() const { return *__pred_; }
86 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Pred const& pred() const { return *__pred_; }
8787
88 _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() {
88 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() {
8989 // Note: this duplicates a check in `optional` but provides a better error message.
9090 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
9191 __pred_.__has_value(), "Trying to call begin() on a filter_view that does not have a valid predicate.");
......@@ -99,7 +99,7 @@ public:
9999 }
100100 }
101101
102 _LIBCPP_HIDE_FROM_ABI constexpr auto end() {
102 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() {
103103 if constexpr (common_range<_View>)
104104 return __iterator{*this, ranges::end(__base_)};
105105 else
......@@ -148,10 +148,10 @@ public:
148148 _LIBCPP_HIDE_FROM_ABI constexpr __iterator(filter_view& __parent, iterator_t<_View> __current)
149149 : __current_(std::move(__current)), __parent_(std::addressof(__parent)) {}
150150
151 _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> const& base() const& noexcept { return __current_; }
152 _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> base() && { return std::move(__current_); }
151 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> const& base() const& noexcept { return __current_; }
152 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> base() && { return std::move(__current_); }
153153
154 _LIBCPP_HIDE_FROM_ABI constexpr range_reference_t<_View> operator*() const { return *__current_; }
154 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_reference_t<_View> operator*() const { return *__current_; }
155155 _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> operator->() const
156156 requires __has_arrow<iterator_t<_View>> && copyable<iterator_t<_View>>
157157 {
......@@ -194,7 +194,7 @@ public:
194194 return __x.__current_ == __y.__current_;
195195 }
196196
197 _LIBCPP_HIDE_FROM_ABI friend constexpr range_rvalue_reference_t<_View>
197 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr range_rvalue_reference_t<_View>
198198 iter_move(__iterator const& __it) noexcept(noexcept(ranges::iter_move(__it.__current_))) {
199199 return ranges::iter_move(__it.__current_);
200200 }
......@@ -218,7 +218,7 @@ public:
218218
219219 _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(filter_view& __parent) : __end_(ranges::end(__parent.__base_)) {}
220220
221 _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_View> base() const { return __end_; }
221 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_View> base() const { return __end_; }
222222
223223 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(__iterator const& __x, __sentinel const& __y) {
224224 return __x.__current_ == __y.__end_;
lib/libcxx/include/__ranges/iota_view.h+41-22
......@@ -30,6 +30,7 @@
3030#include <__ranges/movable_box.h>
3131#include <__ranges/view_interface.h>
3232#include <__type_traits/conditional.h>
33#include <__type_traits/decay.h>
3334#include <__type_traits/is_nothrow_constructible.h>
3435#include <__type_traits/make_unsigned.h>
3536#include <__type_traits/type_identity.h>
......@@ -57,11 +58,17 @@ struct __get_wider_signed {
5758 return type_identity<int>{};
5859 else if constexpr (sizeof(_Int) < sizeof(long))
5960 return type_identity<long>{};
60 else
61 else if constexpr (sizeof(_Int) < sizeof(long long))
6162 return type_identity<long long>{};
62
63 static_assert(
64 sizeof(_Int) <= sizeof(long long), "Found integer-like type that is bigger than largest integer like type.");
63# if _LIBCPP_HAS_INT128
64 else if constexpr (sizeof(_Int) <= sizeof(__int128))
65 return type_identity<__int128>{};
66# else
67 else if constexpr (sizeof(_Int) <= sizeof(long long))
68 return type_identity<long long>{};
69# endif
70 else
71 static_assert(false, "Found integer-like type that is bigger than the largest integer like type.");
6572 }
6673
6774 using type = typename decltype(__call())::type;
......@@ -125,7 +132,8 @@ class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
125132
126133 _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {}
127134
128 _LIBCPP_HIDE_FROM_ABI constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
135 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Start operator*() const
136 noexcept(is_nothrow_copy_constructible_v<_Start>) {
129137 return __value_;
130138 }
131139
......@@ -189,7 +197,7 @@ class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
189197 return *this;
190198 }
191199
192 _LIBCPP_HIDE_FROM_ABI constexpr _Start operator[](difference_type __n) const
200 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Start operator[](difference_type __n) const
193201 requires __advanceable<_Start>
194202 {
195203 return _Start(__value_ + __n);
......@@ -231,27 +239,28 @@ class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
231239 return __x.__value_ <=> __y.__value_;
232240 }
233241
234 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n)
242 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n)
235243 requires __advanceable<_Start>
236244 {
237245 __i += __n;
238246 return __i;
239247 }
240248
241 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i)
249 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i)
242250 requires __advanceable<_Start>
243251 {
244252 return __i + __n;
245253 }
246254
247 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n)
255 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n)
248256 requires __advanceable<_Start>
249257 {
250258 __i -= __n;
251259 return __i;
252260 }
253261
254 _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
262 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type
263 operator-(const __iterator& __x, const __iterator& __y)
255264 requires __advanceable<_Start>
256265 {
257266 if constexpr (__integer_like<_Start>) {
......@@ -282,14 +291,14 @@ class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
282291 return __x.__value_ == __y.__bound_sentinel_;
283292 }
284293
285 _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Start>
294 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Start>
286295 operator-(const __iterator& __x, const __sentinel& __y)
287296 requires sized_sentinel_for<_BoundSentinel, _Start>
288297 {
289298 return __x.__value_ - __y.__bound_sentinel_;
290299 }
291300
292 _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Start>
301 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Start>
293302 operator-(const __sentinel& __x, const __iterator& __y)
294303 requires sized_sentinel_for<_BoundSentinel, _Start>
295304 {
......@@ -329,24 +338,24 @@ public:
329338 requires(!same_as<_Start, _BoundSentinel> && !same_as<_BoundSentinel, unreachable_sentinel_t>)
330339 : iota_view(std::move(__first.__value_), std::move(__last.__bound_sentinel_)) {}
331340
332 _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() const { return __iterator{__value_}; }
341 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() const { return __iterator{__value_}; }
333342
334 _LIBCPP_HIDE_FROM_ABI constexpr auto end() const {
343 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const {
335344 if constexpr (same_as<_BoundSentinel, unreachable_sentinel_t>)
336345 return unreachable_sentinel;
337346 else
338347 return __sentinel{__bound_sentinel_};
339348 }
340349
341 _LIBCPP_HIDE_FROM_ABI constexpr __iterator end() const
350 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator end() const
342351 requires same_as<_Start, _BoundSentinel>
343352 {
344353 return __iterator{__bound_sentinel_};
345354 }
346355
347 _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const { return __value_ == __bound_sentinel_; }
356 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const { return __value_ == __bound_sentinel_; }
348357
349 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
358 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
350359 requires(same_as<_Start, _BoundSentinel> && __advanceable<_Start>) ||
351360 (integral<_Start> && integral<_BoundSentinel>) || sized_sentinel_for<_BoundSentinel, _Start>
352361 {
......@@ -374,14 +383,15 @@ namespace views {
374383namespace __iota {
375384struct __fn {
376385 template <class _Start>
377 _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Start&& __start) const
378 noexcept(noexcept(ranges::iota_view(std::forward<_Start>(__start))))
379 -> decltype(ranges::iota_view(std::forward<_Start>(__start))) {
380 return ranges::iota_view(std::forward<_Start>(__start));
386 requires(requires(_Start __s) { ranges::iota_view<decay_t<_Start>>(std::forward<_Start>(__s)); })
387 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Start&& __start) const
388 noexcept(noexcept(ranges::iota_view<decay_t<_Start>>(std::forward<_Start>(__start)))) {
389 return ranges::iota_view<decay_t<_Start>>(std::forward<_Start>(__start));
381390 }
382391
383392 template <class _Start, class _BoundSentinel>
384 _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Start&& __start, _BoundSentinel&& __bound_sentinel) const noexcept(
393 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto
394 operator()(_Start&& __start, _BoundSentinel&& __bound_sentinel) const noexcept(
385395 noexcept(ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel))))
386396 -> decltype(ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel))) {
387397 return ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel));
......@@ -392,6 +402,15 @@ struct __fn {
392402inline namespace __cpo {
393403inline constexpr auto iota = __iota::__fn{};
394404} // namespace __cpo
405
406# if _LIBCPP_STD_VER >= 26
407
408inline constexpr auto indices = [] [[nodiscard]] (__integer_like auto __size) static {
409 return ranges::views::iota(decltype(__size){}, __size);
410};
411
412# endif
413
395414} // namespace views
396415} // namespace ranges
397416
lib/libcxx/include/__ranges/owning_view.h+15-15
......@@ -49,52 +49,52 @@ public:
4949 _LIBCPP_HIDE_FROM_ABI owning_view(owning_view&&) = default;
5050 _LIBCPP_HIDE_FROM_ABI owning_view& operator=(owning_view&&) = default;
5151
52 _LIBCPP_HIDE_FROM_ABI constexpr _Rp& base() & noexcept { return __r_; }
53 _LIBCPP_HIDE_FROM_ABI constexpr const _Rp& base() const& noexcept { return __r_; }
54 _LIBCPP_HIDE_FROM_ABI constexpr _Rp&& base() && noexcept { return std::move(__r_); }
55 _LIBCPP_HIDE_FROM_ABI constexpr const _Rp&& base() const&& noexcept { return std::move(__r_); }
56
57 _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Rp> begin() { return ranges::begin(__r_); }
58 _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Rp> end() { return ranges::end(__r_); }
59 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
52 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Rp& base() & noexcept { return __r_; }
53 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Rp& base() const& noexcept { return __r_; }
54 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Rp&& base() && noexcept { return std::move(__r_); }
55 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Rp&& base() const&& noexcept { return std::move(__r_); }
56
57 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Rp> begin() { return ranges::begin(__r_); }
58 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Rp> end() { return ranges::end(__r_); }
59 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
6060 requires range<const _Rp>
6161 {
6262 return ranges::begin(__r_);
6363 }
64 _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
64 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
6565 requires range<const _Rp>
6666 {
6767 return ranges::end(__r_);
6868 }
6969
70 _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
70 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
7171 requires requires { ranges::empty(__r_); }
7272 {
7373 return ranges::empty(__r_);
7474 }
75 _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
75 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
7676 requires requires { ranges::empty(__r_); }
7777 {
7878 return ranges::empty(__r_);
7979 }
8080
81 _LIBCPP_HIDE_FROM_ABI constexpr auto size()
81 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size()
8282 requires sized_range<_Rp>
8383 {
8484 return ranges::size(__r_);
8585 }
86 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
86 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
8787 requires sized_range<const _Rp>
8888 {
8989 return ranges::size(__r_);
9090 }
9191
92 _LIBCPP_HIDE_FROM_ABI constexpr auto data()
92 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto data()
9393 requires contiguous_range<_Rp>
9494 {
9595 return ranges::data(__r_);
9696 }
97 _LIBCPP_HIDE_FROM_ABI constexpr auto data() const
97 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto data() const
9898 requires contiguous_range<const _Rp>
9999 {
100100 return ranges::data(__r_);
lib/libcxx/include/__ranges/ref_view.h+6-6
......@@ -51,24 +51,24 @@ public:
5151 _LIBCPP_HIDE_FROM_ABI constexpr ref_view(_Tp&& __t)
5252 : __range_(std::addressof(static_cast<_Range&>(std::forward<_Tp>(__t)))) {}
5353
54 _LIBCPP_HIDE_FROM_ABI constexpr _Range& base() const { return *__range_; }
54 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Range& base() const { return *__range_; }
5555
56 _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Range> begin() const { return ranges::begin(*__range_); }
57 _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Range> end() const { return ranges::end(*__range_); }
56 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Range> begin() const { return ranges::begin(*__range_); }
57 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Range> end() const { return ranges::end(*__range_); }
5858
59 _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
59 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
6060 requires requires { ranges::empty(*__range_); }
6161 {
6262 return ranges::empty(*__range_);
6363 }
6464
65 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
65 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
6666 requires sized_range<_Range>
6767 {
6868 return ranges::size(*__range_);
6969 }
7070
71 _LIBCPP_HIDE_FROM_ABI constexpr auto data() const
71 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto data() const
7272 requires contiguous_range<_Range>
7373 {
7474 return ranges::data(*__range_);
lib/libcxx/include/__ranges/repeat_view.h+17-10
......@@ -108,17 +108,21 @@ public:
108108 __bound_ >= 0, "The behavior is undefined if Bound is not unreachable_sentinel_t and bound is negative");
109109 }
110110
111 _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() const { return __iterator(std::addressof(*__value_)); }
111 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() const {
112 return __iterator(std::addressof(*__value_));
113 }
112114
113 _LIBCPP_HIDE_FROM_ABI constexpr __iterator end() const
115 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator end() const
114116 requires(!same_as<_Bound, unreachable_sentinel_t>)
115117 {
116118 return __iterator(std::addressof(*__value_), __bound_);
117119 }
118120
119 _LIBCPP_HIDE_FROM_ABI constexpr unreachable_sentinel_t end() const noexcept { return unreachable_sentinel; }
121 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr unreachable_sentinel_t end() const noexcept {
122 return unreachable_sentinel;
123 }
120124
121 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
125 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
122126 requires(!same_as<_Bound, unreachable_sentinel_t>)
123127 {
124128 return std::__to_unsigned_like(__bound_);
......@@ -152,7 +156,7 @@ public:
152156
153157 _LIBCPP_HIDE_FROM_ABI __iterator() = default;
154158
155 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const noexcept { return *__value_; }
159 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const noexcept { return *__value_; }
156160
157161 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
158162 ++__current_;
......@@ -192,7 +196,9 @@ public:
192196 return *this;
193197 }
194198
195 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](difference_type __n) const noexcept { return *(*this + __n); }
199 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](difference_type __n) const noexcept {
200 return *(*this + __n);
201 }
196202
197203 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
198204 return __x.__current_ == __y.__current_;
......@@ -202,22 +208,23 @@ public:
202208 return __x.__current_ <=> __y.__current_;
203209 }
204210
205 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n) {
211 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n) {
206212 __i += __n;
207213 return __i;
208214 }
209215
210 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i) {
216 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i) {
211217 __i += __n;
212218 return __i;
213219 }
214220
215 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n) {
221 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n) {
216222 __i -= __n;
217223 return __i;
218224 }
219225
220 _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) {
226 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type
227 operator-(const __iterator& __x, const __iterator& __y) {
221228 return static_cast<difference_type>(__x.__current_) - static_cast<difference_type>(__y.__current_);
222229 }
223230
lib/libcxx/include/__ranges/single_view.h+8-8
......@@ -63,21 +63,21 @@ public:
6363 _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(in_place_t, _Args&&... __args)
6464 : __value_{in_place, std::forward<_Args>(__args)...} {}
6565
66 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* begin() noexcept { return data(); }
66 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp* begin() noexcept { return data(); }
6767
68 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* begin() const noexcept { return data(); }
68 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* begin() const noexcept { return data(); }
6969
70 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* end() noexcept { return data() + 1; }
70 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp* end() noexcept { return data() + 1; }
7171
72 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* end() const noexcept { return data() + 1; }
72 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* end() const noexcept { return data() + 1; }
7373
74 _LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return false; }
74 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return false; }
7575
76 _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 1; }
76 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 1; }
7777
78 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* data() noexcept { return __value_.operator->(); }
78 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp* data() noexcept { return __value_.operator->(); }
7979
80 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
80 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
8181};
8282
8383template <class _Tp>
lib/libcxx/include/__ranges/take_view.h+9-9
......@@ -75,15 +75,15 @@ public:
7575 _LIBCPP_ASSERT_UNCATEGORIZED(__count >= 0, "count has to be greater than or equal to zero");
7676 }
7777
78 _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
78 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
7979 requires copy_constructible<_View>
8080 {
8181 return __base_;
8282 }
8383
84 _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
84 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
8585
86 _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
86 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
8787 requires(!__simple_view<_View>)
8888 {
8989 if constexpr (sized_range<_View>) {
......@@ -99,7 +99,7 @@ public:
9999 }
100100 }
101101
102 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
102 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
103103 requires range<const _View>
104104 {
105105 if constexpr (sized_range<const _View>) {
......@@ -115,7 +115,7 @@ public:
115115 }
116116 }
117117
118 _LIBCPP_HIDE_FROM_ABI constexpr auto end()
118 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end()
119119 requires(!__simple_view<_View>)
120120 {
121121 if constexpr (sized_range<_View>) {
......@@ -129,7 +129,7 @@ public:
129129 }
130130 }
131131
132 _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
132 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
133133 requires range<const _View>
134134 {
135135 if constexpr (sized_range<const _View>) {
......@@ -143,14 +143,14 @@ public:
143143 }
144144 }
145145
146 _LIBCPP_HIDE_FROM_ABI constexpr auto size()
146 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size()
147147 requires sized_range<_View>
148148 {
149149 auto __n = ranges::size(__base_);
150150 return ranges::min(__n, static_cast<decltype(__n)>(__count_));
151151 }
152152
153 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
153 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
154154 requires sized_range<const _View>
155155 {
156156 auto __n = ranges::size(__base_);
......@@ -178,7 +178,7 @@ public:
178178 requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
179179 : __end_(std::move(__s.__end_)) {}
180180
181 _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; }
181 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; }
182182
183183 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) {
184184 return __lhs.count() == 0 || __lhs.base() == __rhs.__end_;
lib/libcxx/include/__ranges/transform_view.h+1-2
......@@ -13,7 +13,6 @@
1313#include <__compare/three_way_comparable.h>
1414#include <__concepts/constructible.h>
1515#include <__concepts/convertible_to.h>
16#include <__concepts/copyable.h>
1716#include <__concepts/derived_from.h>
1817#include <__concepts/equality_comparable.h>
1918#include <__concepts/invocable.h>
......@@ -64,7 +63,7 @@ concept __regular_invocable_with_range_ref = regular_invocable<_Fn, range_refere
6463template <class _View, class _Fn>
6564concept __transform_view_constraints =
6665 view<_View> && is_object_v<_Fn> && regular_invocable<_Fn&, range_reference_t<_View>> &&
67 __is_referenceable_v<invoke_result_t<_Fn&, range_reference_t<_View>>>;
66 __referenceable<invoke_result_t<_Fn&, range_reference_t<_View>>>;
6867
6968# if _LIBCPP_STD_VER >= 23
7069template <input_range _View, move_constructible _Fn>
lib/libcxx/include/__ranges/view_interface.h+10-10
......@@ -87,35 +87,35 @@ public:
8787 }
8888
8989 template <class _D2 = _Derived>
90 _LIBCPP_HIDE_FROM_ABI constexpr auto data()
90 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto data()
9191 requires contiguous_iterator<iterator_t<_D2>>
9292 {
9393 return std::to_address(ranges::begin(__derived()));
9494 }
9595
9696 template <class _D2 = _Derived>
97 _LIBCPP_HIDE_FROM_ABI constexpr auto data() const
97 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto data() const
9898 requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>>
9999 {
100100 return std::to_address(ranges::begin(__derived()));
101101 }
102102
103103 template <class _D2 = _Derived>
104 _LIBCPP_HIDE_FROM_ABI constexpr auto size()
104 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size()
105105 requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
106106 {
107107 return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
108108 }
109109
110110 template <class _D2 = _Derived>
111 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
111 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
112112 requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
113113 {
114114 return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
115115 }
116116
117117 template <class _D2 = _Derived>
118 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front()
118 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front()
119119 requires forward_range<_D2>
120120 {
121121 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
......@@ -124,7 +124,7 @@ public:
124124 }
125125
126126 template <class _D2 = _Derived>
127 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front() const
127 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front() const
128128 requires forward_range<const _D2>
129129 {
130130 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
......@@ -133,7 +133,7 @@ public:
133133 }
134134
135135 template <class _D2 = _Derived>
136 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back()
136 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back()
137137 requires bidirectional_range<_D2> && common_range<_D2>
138138 {
139139 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
......@@ -142,7 +142,7 @@ public:
142142 }
143143
144144 template <class _D2 = _Derived>
145 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back() const
145 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back() const
146146 requires bidirectional_range<const _D2> && common_range<const _D2>
147147 {
148148 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
......@@ -151,12 +151,12 @@ public:
151151 }
152152
153153 template <random_access_range _RARange = _Derived>
154 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) {
154 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) {
155155 return ranges::begin(__derived())[__index];
156156 }
157157
158158 template <random_access_range _RARange = const _Derived>
159 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const {
159 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const {
160160 return ranges::begin(__derived())[__index];
161161 }
162162};
lib/libcxx/include/__ranges/zip_transform_view.h created+357
......@@ -0,0 +1,357 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___RANGES_ZIP_TRANSFORM_VIEW_H
11#define _LIBCPP___RANGES_ZIP_TRANSFORM_VIEW_H
12
13#include <__config>
14
15#include <__concepts/constructible.h>
16#include <__concepts/convertible_to.h>
17#include <__concepts/derived_from.h>
18#include <__concepts/equality_comparable.h>
19#include <__concepts/invocable.h>
20#include <__functional/invoke.h>
21#include <__iterator/concepts.h>
22#include <__iterator/incrementable_traits.h>
23#include <__iterator/iterator_traits.h>
24#include <__memory/addressof.h>
25#include <__ranges/access.h>
26#include <__ranges/all.h>
27#include <__ranges/concepts.h>
28#include <__ranges/empty_view.h>
29#include <__ranges/movable_box.h>
30#include <__ranges/view_interface.h>
31#include <__ranges/zip_view.h>
32#include <__type_traits/decay.h>
33#include <__type_traits/invoke.h>
34#include <__type_traits/is_object.h>
35#include <__type_traits/is_reference.h>
36#include <__type_traits/is_referenceable.h>
37#include <__type_traits/maybe_const.h>
38#include <__type_traits/remove_cvref.h>
39#include <__utility/forward.h>
40#include <__utility/in_place.h>
41#include <__utility/move.h>
42#include <tuple> // for std::apply
43
44#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
45# pragma GCC system_header
46#endif
47
48_LIBCPP_PUSH_MACROS
49#include <__undef_macros>
50_LIBCPP_BEGIN_NAMESPACE_STD
51
52#if _LIBCPP_STD_VER >= 23
53
54namespace ranges {
55
56template <move_constructible _Fn, input_range... _Views>
57 requires(view<_Views> && ...) &&
58 (sizeof...(_Views) > 0) && is_object_v<_Fn> && regular_invocable<_Fn&, range_reference_t<_Views>...> &&
59 __referenceable<invoke_result_t<_Fn&, range_reference_t<_Views>...>>
60class zip_transform_view : public view_interface<zip_transform_view<_Fn, _Views...>> {
61 _LIBCPP_NO_UNIQUE_ADDRESS zip_view<_Views...> __zip_;
62 _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Fn> __fun_;
63
64 using _InnerView _LIBCPP_NODEBUG = zip_view<_Views...>;
65 template <bool _Const>
66 using __ziperator _LIBCPP_NODEBUG = iterator_t<__maybe_const<_Const, _InnerView>>;
67 template <bool _Const>
68 using __zentinel _LIBCPP_NODEBUG = sentinel_t<__maybe_const<_Const, _InnerView>>;
69
70 template <bool>
71 class __iterator;
72
73 template <bool>
74 class __sentinel;
75
76public:
77 _LIBCPP_HIDE_FROM_ABI zip_transform_view() = default;
78
79 _LIBCPP_HIDE_FROM_ABI constexpr explicit zip_transform_view(_Fn __fun, _Views... __views)
80 : __zip_(std::move(__views)...), __fun_(in_place, std::move(__fun)) {}
81
82 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() { return __iterator<false>(*this, __zip_.begin()); }
83
84 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
85 requires range<const _InnerView> && regular_invocable<const _Fn&, range_reference_t<const _Views>...>
86 {
87 return __iterator<true>(*this, __zip_.begin());
88 }
89
90 _LIBCPP_HIDE_FROM_ABI constexpr auto end() {
91 if constexpr (common_range<_InnerView>) {
92 return __iterator<false>(*this, __zip_.end());
93 } else {
94 return __sentinel<false>(__zip_.end());
95 }
96 }
97
98 _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
99 requires range<const _InnerView> && regular_invocable<const _Fn&, range_reference_t<const _Views>...>
100 {
101 if constexpr (common_range<const _InnerView>) {
102 return __iterator<true>(*this, __zip_.end());
103 } else {
104 return __sentinel<true>(__zip_.end());
105 }
106 }
107
108 _LIBCPP_HIDE_FROM_ABI constexpr auto size()
109 requires sized_range<_InnerView>
110 {
111 return __zip_.size();
112 }
113
114 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
115 requires sized_range<const _InnerView>
116 {
117 return __zip_.size();
118 }
119};
120
121template <class _Fn, class... _Ranges>
122zip_transform_view(_Fn, _Ranges&&...) -> zip_transform_view<_Fn, views::all_t<_Ranges>...>;
123
124template <bool _Const, class _Fn, class... _Views>
125struct __zip_transform_iterator_category_base {};
126
127template <bool _Const, class _Fn, class... _Views>
128 requires forward_range<__maybe_const<_Const, zip_view<_Views...>>>
129struct __zip_transform_iterator_category_base<_Const, _Fn, _Views...> {
130private:
131 template <class _View>
132 using __tag _LIBCPP_NODEBUG = typename iterator_traits<iterator_t<__maybe_const<_Const, _View>>>::iterator_category;
133
134 static consteval auto __get_iterator_category() {
135 if constexpr (!is_reference_v<invoke_result_t<__maybe_const<_Const, _Fn>&,
136 range_reference_t<__maybe_const<_Const, _Views>>...>>) {
137 return input_iterator_tag();
138 } else if constexpr ((derived_from<__tag<_Views>, random_access_iterator_tag> && ...)) {
139 return random_access_iterator_tag();
140 } else if constexpr ((derived_from<__tag<_Views>, bidirectional_iterator_tag> && ...)) {
141 return bidirectional_iterator_tag();
142 } else if constexpr ((derived_from<__tag<_Views>, forward_iterator_tag> && ...)) {
143 return forward_iterator_tag();
144 } else {
145 return input_iterator_tag();
146 }
147 }
148
149public:
150 using iterator_category = decltype(__get_iterator_category());
151};
152
153template <move_constructible _Fn, input_range... _Views>
154 requires(view<_Views> && ...) &&
155 (sizeof...(_Views) > 0) && is_object_v<_Fn> && regular_invocable<_Fn&, range_reference_t<_Views>...> &&
156 __referenceable<invoke_result_t<_Fn&, range_reference_t<_Views>...>>
157template <bool _Const>
158class zip_transform_view<_Fn, _Views...>::__iterator
159 : public __zip_transform_iterator_category_base<_Const, _Fn, _Views...> {
160 using _Parent _LIBCPP_NODEBUG = __maybe_const<_Const, zip_transform_view>;
161 using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _InnerView>;
162
163 friend zip_transform_view<_Fn, _Views...>;
164
165 _Parent* __parent_ = nullptr;
166 __ziperator<_Const> __inner_;
167
168 _LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent& __parent, __ziperator<_Const> __inner)
169 : __parent_(std::addressof(__parent)), __inner_(std::move(__inner)) {}
170
171 _LIBCPP_HIDE_FROM_ABI constexpr auto __get_deref_and_invoke() const noexcept {
172 return [&__fun = *__parent_->__fun_](const auto&... __iters) noexcept(noexcept(std::invoke(
173 *__parent_->__fun_, *__iters...))) -> decltype(auto) { return std::invoke(__fun, *__iters...); };
174 }
175
176public:
177 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
178 using value_type =
179 remove_cvref_t<invoke_result_t<__maybe_const<_Const, _Fn>&, range_reference_t<__maybe_const<_Const, _Views>>...>>;
180 using difference_type = range_difference_t<_Base>;
181
182 _LIBCPP_HIDE_FROM_ABI __iterator() = default;
183 _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
184 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
185 : __parent_(__i.__parent_), __inner_(std::move(__i.__inner_)) {}
186
187 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const
188 noexcept(noexcept(std::apply(__get_deref_and_invoke(), __zip_view_iterator_access::__get_underlying(__inner_)))) {
189 return std::apply(__get_deref_and_invoke(), __zip_view_iterator_access::__get_underlying(__inner_));
190 }
191
192 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
193 ++__inner_;
194 return *this;
195 }
196
197 _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; }
198
199 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
200 requires forward_range<_Base>
201 {
202 auto __tmp = *this;
203 ++*this;
204 return __tmp;
205 }
206
207 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
208 requires bidirectional_range<_Base>
209 {
210 --__inner_;
211 return *this;
212 }
213
214 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
215 requires bidirectional_range<_Base>
216 {
217 auto __tmp = *this;
218 --*this;
219 return __tmp;
220 }
221
222 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __x)
223 requires random_access_range<_Base>
224 {
225 __inner_ += __x;
226 return *this;
227 }
228
229 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __x)
230 requires random_access_range<_Base>
231 {
232 __inner_ -= __x;
233 return *this;
234 }
235
236 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const
237 requires random_access_range<_Base>
238 {
239 return std::apply(
240 [&]<class... _Is>(const _Is&... __iters) -> decltype(auto) {
241 return std::invoke(*__parent_->__fun_, __iters[iter_difference_t<_Is>(__n)]...);
242 },
243 __zip_view_iterator_access::__get_underlying(__inner_));
244 }
245
246 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
247 requires equality_comparable<__ziperator<_Const>>
248 {
249 return __x.__inner_ == __y.__inner_;
250 }
251
252 _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
253 requires random_access_range<_Base>
254 {
255 return __x.__inner_ <=> __y.__inner_;
256 }
257
258 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __i, difference_type __n)
259 requires random_access_range<_Base>
260 {
261 return __iterator(*__i.__parent_, __i.__inner_ + __n);
262 }
263
264 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, const __iterator& __i)
265 requires random_access_range<_Base>
266 {
267 return __iterator(*__i.__parent_, __i.__inner_ + __n);
268 }
269
270 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __i, difference_type __n)
271 requires random_access_range<_Base>
272 {
273 return __iterator(*__i.__parent_, __i.__inner_ - __n);
274 }
275
276 _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
277 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
278 {
279 return __x.__inner_ - __y.__inner_;
280 }
281};
282
283template <move_constructible _Fn, input_range... _Views>
284 requires(view<_Views> && ...) &&
285 (sizeof...(_Views) > 0) && is_object_v<_Fn> && regular_invocable<_Fn&, range_reference_t<_Views>...> &&
286 __referenceable<invoke_result_t<_Fn&, range_reference_t<_Views>...>>
287template <bool _Const>
288class zip_transform_view<_Fn, _Views...>::__sentinel {
289 __zentinel<_Const> __inner_;
290
291 friend zip_transform_view<_Fn, _Views...>;
292
293 _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(__zentinel<_Const> __inner) : __inner_(__inner) {}
294
295public:
296 _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
297
298 _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __i)
299 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
300 : __inner_(__i.__inner_) {}
301
302 template <bool _OtherConst>
303 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
304 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
305 return __x.__inner_ == __y.__inner_;
306 }
307
308 template <bool _OtherConst>
309 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
310 _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _InnerView>>
311 operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
312 return __x.__inner_ - __y.__inner_;
313 }
314
315 template <bool _OtherConst>
316 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
317 _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _InnerView>>
318 operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) {
319 return __x.__inner_ - __y.__inner_;
320 }
321};
322
323namespace views {
324namespace __zip_transform {
325
326struct __fn {
327 template <class _Fn>
328 requires(move_constructible<decay_t<_Fn>> && regular_invocable<decay_t<_Fn>&> &&
329 is_object_v<invoke_result_t<decay_t<_Fn>&>>)
330 _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Fn&&) const
331 noexcept(noexcept(auto(views::empty<decay_t<invoke_result_t<decay_t<_Fn>&>>>))) {
332 return views::empty<decay_t<invoke_result_t<decay_t<_Fn>&>>>;
333 }
334
335 template <class _Fn, class... _Ranges>
336 requires(sizeof...(_Ranges) > 0)
337 _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Fn&& __fun, _Ranges&&... __rs) const
338 noexcept(noexcept(zip_transform_view(std::forward<_Fn>(__fun), std::forward<_Ranges>(__rs)...)))
339 -> decltype(zip_transform_view(std::forward<_Fn>(__fun), std::forward<_Ranges>(__rs)...)) {
340 return zip_transform_view(std::forward<_Fn>(__fun), std::forward<_Ranges>(__rs)...);
341 }
342};
343
344} // namespace __zip_transform
345inline namespace __cpo {
346inline constexpr auto zip_transform = __zip_transform::__fn{};
347} // namespace __cpo
348} // namespace views
349} // namespace ranges
350
351#endif // _LIBCPP_STD_VER >= 23
352
353_LIBCPP_END_NAMESPACE_STD
354
355_LIBCPP_POP_MACROS
356
357#endif // _LIBCPP___RANGES_ZIP_TRANSFORM_VIEW_H
lib/libcxx/include/__ranges/zip_view.h+20-20
......@@ -31,6 +31,7 @@
3131#include <__ranges/enable_borrowed_range.h>
3232#include <__ranges/size.h>
3333#include <__ranges/view_interface.h>
34#include <__tuple/tuple_transform.h>
3435#include <__type_traits/is_nothrow_constructible.h>
3536#include <__type_traits/make_unsigned.h>
3637#include <__utility/declval.h>
......@@ -58,15 +59,6 @@ concept __zip_is_common =
5859 (!(bidirectional_range<_Ranges> && ...) && (common_range<_Ranges> && ...)) ||
5960 ((random_access_range<_Ranges> && ...) && (sized_range<_Ranges> && ...));
6061
61template <class _Fun, class _Tuple>
62_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_transform(_Fun&& __f, _Tuple&& __tuple) {
63 return std::apply(
64 [&]<class... _Types>(_Types&&... __elements) {
65 return tuple<invoke_result_t<_Fun&, _Types>...>(std::invoke(__f, std::forward<_Types>(__elements))...);
66 },
67 std::forward<_Tuple>(__tuple));
68}
69
7062template <class _Fun, class _Tuple>
7163_LIBCPP_HIDE_FROM_ABI constexpr void __tuple_for_each(_Fun&& __f, _Tuple&& __tuple) {
7264 std::apply(
......@@ -145,24 +137,24 @@ public:
145137 _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
146138 requires(!(__simple_view<_Views> && ...))
147139 {
148 return __iterator<false>(ranges::__tuple_transform(ranges::begin, __views_));
140 return __iterator<false>(std::__tuple_transform(ranges::begin, __views_));
149141 }
150142
151143 _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
152144 requires(range<const _Views> && ...)
153145 {
154 return __iterator<true>(ranges::__tuple_transform(ranges::begin, __views_));
146 return __iterator<true>(std::__tuple_transform(ranges::begin, __views_));
155147 }
156148
157149 _LIBCPP_HIDE_FROM_ABI constexpr auto end()
158150 requires(!(__simple_view<_Views> && ...))
159151 {
160152 if constexpr (!__zip_is_common<_Views...>) {
161 return __sentinel<false>(ranges::__tuple_transform(ranges::end, __views_));
153 return __sentinel<false>(std::__tuple_transform(ranges::end, __views_));
162154 } else if constexpr ((random_access_range<_Views> && ...)) {
163155 return begin() + iter_difference_t<__iterator<false>>(size());
164156 } else {
165 return __iterator<false>(ranges::__tuple_transform(ranges::end, __views_));
157 return __iterator<false>(std::__tuple_transform(ranges::end, __views_));
166158 }
167159 }
168160
......@@ -170,11 +162,11 @@ public:
170162 requires(range<const _Views> && ...)
171163 {
172164 if constexpr (!__zip_is_common<const _Views...>) {
173 return __sentinel<true>(ranges::__tuple_transform(ranges::end, __views_));
165 return __sentinel<true>(std::__tuple_transform(ranges::end, __views_));
174166 } else if constexpr ((random_access_range<const _Views> && ...)) {
175167 return begin() + iter_difference_t<__iterator<true>>(size());
176168 } else {
177 return __iterator<true>(ranges::__tuple_transform(ranges::end, __views_));
169 return __iterator<true>(std::__tuple_transform(ranges::end, __views_));
178170 }
179171 }
180172
......@@ -186,7 +178,7 @@ public:
186178 using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>;
187179 return ranges::min({_CT(__sizes)...});
188180 },
189 ranges::__tuple_transform(ranges::size, __views_));
181 std::__tuple_transform(ranges::size, __views_));
190182 }
191183
192184 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
......@@ -197,7 +189,7 @@ public:
197189 using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>;
198190 return ranges::min({_CT(__sizes)...});
199191 },
200 ranges::__tuple_transform(ranges::size, __views_));
192 std::__tuple_transform(ranges::size, __views_));
201193 }
202194};
203195
......@@ -235,6 +227,13 @@ struct __zip_view_iterator_category_base<_Const, _Views...> {
235227 using iterator_category = input_iterator_tag;
236228};
237229
230struct __zip_view_iterator_access {
231 template <class _Iter>
232 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_underlying(_Iter& __iter) noexcept {
233 return (__iter.__current_);
234 }
235};
236
238237template <input_range... _Views>
239238 requires(view<_Views> && ...) && (sizeof...(_Views) > 0)
240239template <bool _Const>
......@@ -255,6 +254,7 @@ class zip_view<_Views...>::__iterator : public __zip_view_iterator_category_base
255254 static constexpr bool __is_zip_view_iterator = true;
256255
257256 friend struct __product_iterator_traits<__iterator>;
257 friend __zip_view_iterator_access;
258258
259259public:
260260 using iterator_concept = decltype(ranges::__get_zip_view_iterator_tag<_Const, _Views...>());
......@@ -268,7 +268,7 @@ public:
268268 : __current_(std::move(__i.__current_)) {}
269269
270270 _LIBCPP_HIDE_FROM_ABI constexpr auto operator*() const {
271 return ranges::__tuple_transform([](auto& __i) -> decltype(auto) { return *__i; }, __current_);
271 return std::__tuple_transform([](auto& __i) -> decltype(auto) { return *__i; }, __current_);
272272 }
273273
274274 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
......@@ -318,7 +318,7 @@ public:
318318 _LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type __n) const
319319 requires __zip_all_random_access<_Const, _Views...>
320320 {
321 return ranges::__tuple_transform(
321 return std::__tuple_transform(
322322 [&]<class _Iter>(_Iter& __i) -> decltype(auto) { return __i[iter_difference_t<_Iter>(__n)]; }, __current_);
323323 }
324324
......@@ -377,7 +377,7 @@ public:
377377 _LIBCPP_HIDE_FROM_ABI friend constexpr auto iter_move(const __iterator& __i) noexcept(
378378 (noexcept(ranges::iter_move(std::declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) && ...) &&
379379 (is_nothrow_move_constructible_v<range_rvalue_reference_t<__maybe_const<_Const, _Views>>> && ...)) {
380 return ranges::__tuple_transform(ranges::iter_move, __i.__current_);
380 return std::__tuple_transform(ranges::iter_move, __i.__current_);
381381 }
382382
383383 _LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const __iterator& __l, const __iterator& __r) noexcept(
lib/libcxx/include/__split_buffer+612-240
......@@ -13,10 +13,12 @@
1313#include <__algorithm/max.h>
1414#include <__algorithm/move.h>
1515#include <__algorithm/move_backward.h>
16#include <__assert>
1617#include <__config>
1718#include <__iterator/distance.h>
1819#include <__iterator/iterator_traits.h>
1920#include <__iterator/move_iterator.h>
21#include <__memory/addressof.h>
2022#include <__memory/allocate_at_least.h>
2123#include <__memory/allocator.h>
2224#include <__memory/allocator_traits.h>
......@@ -28,11 +30,9 @@
2830#include <__type_traits/integral_constant.h>
2931#include <__type_traits/is_nothrow_assignable.h>
3032#include <__type_traits/is_nothrow_constructible.h>
31#include <__type_traits/is_replaceable.h>
3233#include <__type_traits/is_swappable.h>
3334#include <__type_traits/is_trivially_destructible.h>
3435#include <__type_traits/is_trivially_relocatable.h>
35#include <__type_traits/remove_reference.h>
3636#include <__utility/forward.h>
3737#include <__utility/move.h>
3838
......@@ -45,25 +45,430 @@ _LIBCPP_PUSH_MACROS
4545
4646_LIBCPP_BEGIN_NAMESPACE_STD
4747
48// __split_buffer allocates a contiguous chunk of memory and stores objects in the range [__begin_, __end_).
49// It has uninitialized memory in the ranges [__first_, __begin_) and [__end_, __cap_). That allows
50// it to grow both in the front and back without having to move the data.
48template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
49class __split_buffer;
50
51template <class _SplitBuffer, class _Tp, class _Allocator>
52class __split_buffer_pointer_layout {
53protected:
54 using value_type = _Tp;
55 using allocator_type = _Allocator;
56 using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;
57 using reference = value_type&;
58 using const_reference = const value_type&;
59 using size_type = typename __alloc_traits::size_type;
60 using difference_type = typename __alloc_traits::difference_type;
61 using pointer = typename __alloc_traits::pointer;
62 using const_pointer = typename __alloc_traits::const_pointer;
63 using iterator = pointer;
64 using const_iterator = const_pointer;
65 using __sentinel_type _LIBCPP_NODEBUG = pointer;
5166
52template <class _Tp, class _Allocator = allocator<_Tp> >
53struct __split_buffer {
5467public:
55 using value_type = _Tp;
56 using allocator_type = _Allocator;
57 using __alloc_rr _LIBCPP_NODEBUG = __libcpp_remove_reference_t<allocator_type>;
58 using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<__alloc_rr>;
59 using reference = value_type&;
60 using const_reference = const value_type&;
61 using size_type = typename __alloc_traits::size_type;
62 using difference_type = typename __alloc_traits::difference_type;
63 using pointer = typename __alloc_traits::pointer;
64 using const_pointer = typename __alloc_traits::const_pointer;
65 using iterator = pointer;
66 using const_iterator = const_pointer;
68 // Can't be defaulted due to _LIBCPP_COMPRESSED_PAIR not being an aggregate in C++03 and C++11.
69 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer_pointer_layout() : __back_cap_(nullptr) {}
70
71 _LIBCPP_CONSTEXPR_SINCE_CXX20
72 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer_pointer_layout(const allocator_type& __alloc)
73 : __back_cap_(nullptr), __alloc_(__alloc) {}
74
75 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __front_cap() _NOEXCEPT { return __front_cap_; }
76
77 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_pointer __front_cap() const _NOEXCEPT {
78 return __front_cap_;
79 }
80
81 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer begin() _NOEXCEPT { return __begin_; }
82
83 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_pointer begin() const _NOEXCEPT { return __begin_; }
84
85 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer end() _NOEXCEPT { return __end_; }
86
87 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer end() const _NOEXCEPT { return __end_; }
88
89 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
90 return static_cast<size_type>(__end_ - __begin_);
91 }
92
93 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __begin_ == __end_; }
94
95 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
96 return static_cast<size_type>(__back_cap_ - __front_cap_);
97 }
98
99 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type& __get_allocator() _NOEXCEPT { return __alloc_; }
100
101 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type const& __get_allocator() const _NOEXCEPT {
102 return __alloc_;
103 }
104
105 // Returns the sentinel object directly. Should be used in conjunction with automatic type deduction,
106 // not explicit types.
107 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __sentinel_type __raw_sentinel() const _NOEXCEPT {
108 return __end_;
109 }
110 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __sentinel_type __raw_capacity() const _NOEXCEPT {
111 return __back_cap_;
112 }
113
114 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_data(pointer __new_first) _NOEXCEPT {
115 __front_cap_ = __new_first;
116 }
117
118 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
119 __set_valid_range(pointer __new_begin, pointer __new_end) _NOEXCEPT {
120 __begin_ = __new_begin;
121 __end_ = __new_end;
122 }
123
124 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
125 __set_valid_range(pointer __new_begin, size_type __new_size) _NOEXCEPT {
126 __begin_ = __new_begin;
127 __end_ = __begin_ + __new_size;
128 }
129
130 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __new_end) _NOEXCEPT {
131 _LIBCPP_ASSERT_INTERNAL(__front_cap_ <= __new_end, "__new_end cannot precede __front_cap_");
132 __end_ = __new_end;
133 }
134
135 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(size_type __new_size) _NOEXCEPT {
136 __end_ = __begin_ + __new_size;
137 }
138
139 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __new_capacity) _NOEXCEPT {
140 __back_cap_ = __front_cap_ + __new_capacity;
141 }
142
143 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(pointer __new_capacity) _NOEXCEPT {
144 __back_cap_ = __new_capacity;
145 }
146
147 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const _NOEXCEPT {
148 return static_cast<size_type>(__begin_ - __front_cap_);
149 }
150
151 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const _NOEXCEPT {
152 return static_cast<size_type>(__back_cap_ - __end_);
153 }
154
155 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT { return *(__end_ - 1); }
156
157 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT { return *(__end_ - 1); }
158
159 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_without_allocator(
160 __split_buffer_pointer_layout<__split_buffer<value_type, allocator_type, __split_buffer_pointer_layout>,
161 value_type,
162 allocator_type>& __other) _NOEXCEPT {
163 std::swap(__front_cap_, __other.__front_cap_);
164 std::swap(__begin_, __other.__begin_);
165 std::swap(__back_cap_, __other.__back_cap_);
166 std::swap(__end_, __other.__end_);
167 }
168
169 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer_pointer_layout& __other) _NOEXCEPT {
170 std::swap(__front_cap_, __other.__front_cap_);
171 std::swap(__begin_, __other.__begin_);
172 std::swap(__back_cap_, __other.__back_cap_);
173 std::swap(__end_, __other.__end_);
174 std::__swap_allocator(__alloc_, __other.__alloc_);
175 }
176
177 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __reset() _NOEXCEPT {
178 __front_cap_ = nullptr;
179 __begin_ = nullptr;
180 __end_ = nullptr;
181 __back_cap_ = nullptr;
182 }
183
184 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
185 __copy_without_alloc(__split_buffer_pointer_layout const& __other)
186 _NOEXCEPT_(is_nothrow_copy_assignable<pointer>::value) {
187 __front_cap_ = __other.__front_cap_;
188 __begin_ = __other.__begin_;
189 __end_ = __other.__end_;
190 __back_cap_ = __other.__back_cap_;
191 }
192
193private:
194 pointer __front_cap_ = nullptr;
195 pointer __begin_ = nullptr;
196 pointer __end_ = nullptr;
197 _LIBCPP_COMPRESSED_PAIR(pointer, __back_cap_, allocator_type, __alloc_);
198
199 template <class, class, class>
200 friend class __split_buffer_pointer_layout;
201};
202
203template <class _SplitBuffer, class _Tp, class _Allocator>
204class __split_buffer_size_layout {
205protected:
206 using value_type = _Tp;
207 using allocator_type = _Allocator;
208 using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;
209 using reference = value_type&;
210 using const_reference = const value_type&;
211 using size_type = typename __alloc_traits::size_type;
212 using difference_type = typename __alloc_traits::difference_type;
213 using pointer = typename __alloc_traits::pointer;
214 using const_pointer = typename __alloc_traits::const_pointer;
215 using iterator = pointer;
216 using const_iterator = const_pointer;
217 using __sentinel_type _LIBCPP_NODEBUG = size_type;
218
219public:
220 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer_size_layout() = default;
221
222 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer_size_layout(const allocator_type& __alloc)
223 : __alloc_(__alloc) {}
224
225 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __front_cap() _NOEXCEPT { return __front_cap_; }
226
227 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_pointer __front_cap() const _NOEXCEPT {
228 return __front_cap_;
229 }
230
231 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer begin() _NOEXCEPT { return __begin_; }
232
233 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_pointer begin() const _NOEXCEPT { return __begin_; }
234
235 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer end() _NOEXCEPT { return __begin_ + __size_; }
236
237 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer end() const _NOEXCEPT { return __begin_ + __size_; }
238
239 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }
240
241 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __size_ == 0; }
242
243 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT { return __cap_; }
244
245 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type& __get_allocator() _NOEXCEPT { return __alloc_; }
246
247 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type const& __get_allocator() const _NOEXCEPT {
248 return __alloc_;
249 }
250
251 // Returns the sentinel object directly. Should be used in conjunction with automatic type deduction,
252 // not explicit types.
253 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __sentinel_type __raw_sentinel() const _NOEXCEPT {
254 return __size_;
255 }
256 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __sentinel_type __raw_capacity() const _NOEXCEPT {
257 return __cap_;
258 }
259
260 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_data(pointer __new_first) _NOEXCEPT {
261 __front_cap_ = __new_first;
262 }
263
264 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
265 __set_valid_range(pointer __new_begin, pointer __new_end) _NOEXCEPT {
266 // Size-based __split_buffers track their size directly: we need to explicitly update the size
267 // when the front is adjusted.
268 __size_ -= __new_begin - __begin_;
269 __begin_ = __new_begin;
270 __set_sentinel(__new_end);
271 }
272
273 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
274 __set_valid_range(pointer __new_begin, size_type __new_size) _NOEXCEPT {
275 // Size-based __split_buffers track their size directly: we need to explicitly update the size
276 // when the front is adjusted.
277 __size_ -= __new_begin - __begin_;
278 __begin_ = __new_begin;
279 __set_sentinel(__new_size);
280 }
281
282 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(pointer __new_end) _NOEXCEPT {
283 _LIBCPP_ASSERT_INTERNAL(__front_cap_ <= __new_end, "__new_end cannot precede __front_cap_");
284 __size_ += __new_end - end();
285 }
286
287 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_sentinel(size_type __new_size) _NOEXCEPT {
288 __size_ = __new_size;
289 }
290
291 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(size_type __new_capacity) _NOEXCEPT {
292 __cap_ = __new_capacity;
293 }
294
295 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __set_capacity(pointer __new_capacity) _NOEXCEPT {
296 __cap_ = __new_capacity - __begin_;
297 }
298
299 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const _NOEXCEPT {
300 return static_cast<size_type>(__begin_ - __front_cap_);
301 }
302
303 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const _NOEXCEPT {
304 // `__cap_ - __end_` tells us the total number of spares when in size-mode. We need to remove
305 // the __front_spare from the count.
306 return __cap_ - __size_ - __front_spare();
307 }
308
309 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT { return __begin_[__size_ - 1]; }
310
311 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
312 return __begin_[__size_ - 1];
313 }
314
315 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_without_allocator(
316 __split_buffer_pointer_layout<__split_buffer<value_type, allocator_type, __split_buffer_pointer_layout>,
317 value_type,
318 allocator_type>& __other) _NOEXCEPT {
319 std::swap(__front_cap_, __other.__front_cap_);
320 std::swap(__begin_, __other.__begin_);
321 std::swap(__cap_, __other.__cap_);
322 std::swap(__size_, __other.__size_);
323 }
324
325 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer_size_layout& __other) _NOEXCEPT {
326 std::swap(__front_cap_, __other.__front_cap_);
327 std::swap(__begin_, __other.__begin_);
328 std::swap(__cap_, __other.__cap_);
329 std::swap(__size_, __other.__size_);
330 std::__swap_allocator(__alloc_, __other.__alloc_);
331 }
332
333 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __reset() _NOEXCEPT {
334 __front_cap_ = nullptr;
335 __begin_ = nullptr;
336 __size_ = 0;
337 __cap_ = 0;
338 }
339
340 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
341 __copy_without_alloc(__split_buffer_size_layout const& __other)
342 _NOEXCEPT_(is_nothrow_copy_assignable<pointer>::value) {
343 __front_cap_ = __other.__front_cap_;
344 __begin_ = __other.__begin_;
345 __cap_ = __other.__cap_;
346 __size_ = __other.__size_;
347 }
348
349private:
350 pointer __front_cap_ = nullptr;
351 pointer __begin_ = nullptr;
352 size_type __size_ = 0;
353 size_type __cap_ = 0;
354 _LIBCPP_NO_UNIQUE_ADDRESS allocator_type __alloc_;
355
356 template <class, class, class>
357 friend class __split_buffer_size_layout;
358};
359
360// `__split_buffer` is a contiguous array data structure. It may hold spare capacity at both ends of
361// the sequence. This allows for a `__split_buffer` to grow from both the front and the back without
362// relocating its contents until it runs out of room. This characteristic sets it apart from
363// `std::vector`, which only holds spare capacity at its end. As such, `__split_buffer` is useful
364// for implementing both `std::vector` and `std::deque`.
365//
366// The sequence is stored as a contiguous chunk of memory delimited by the following "pointers" (`o` denotes
367// uninitialized memory and `x` denotes a valid object):
368//
369// |oooooooooooooooooooxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxoooooooooooooooooooooooo|
370// ^ ^ ^ ^
371// __front_cap_ __begin_ __end_ __back_cap_
372//
373// The range [__front_cap_, __begin_) contains uninitialized memory. It is referred to as the "front spare capacity".
374// The range [__begin_, __end_) contains valid objects. It is referred to as the "valid range".
375// The range [__end_, __back_cap_) contains uninitialized memory. It is referred to as the "back spare capacity".
376//
377// The layout of `__split_buffer` is determined by the `_Layout` template template parameter. This
378// `_Layout` allows the above pointers to be stored as different representations, such as integer
379// offsets. A layout class template must provide the following interface:
380//
381// template<class _Tp, class _Allocator, class _Layout>
382// class __layout {
383// protected:
384// using value_type = _Tp;
385// using allocator_type = _Allocator;
386// using __alloc_traits = allocator_traits<allocator_type>;
387// using reference = value_type&;
388// using const_reference = const value_type&;
389// using size_type = typename __alloc_traits::size_type;
390// using difference_type = typename __alloc_traits::difference_type;
391// using pointer = typename __alloc_traits::pointer;
392// using const_pointer = typename __alloc_traits::const_pointer;
393// using iterator = pointer;
394// using const_iterator = const_pointer;
395// using __sentinel_type = /* type that represents the layout's sentinel */;
396//
397// public:
398// __layout() = default;
399// explicit __layout(const allocator_type&);
400//
401// pointer __front_cap();
402// const_pointer __front_cap() const;
403//
404// pointer begin();
405// const_pointer begin() const;
406//
407// pointer end();
408// pointer end() const;
409//
410// size_type size() const;
411// bool empty() const;
412// size_type capacity() const;
413//
414// allocator_type& __get_allocator();
415// allocator_type const& __get_allocator() const;
416//
417// __sentinel_type __raw_sentinel() const;
418// __sentinel_type __raw_capacity() const;
419//
420// void __set_data(pointer);
421// void __set_valid_range(pointer __begin, pointer __end);
422// void __set_valid_range(pointer __begin, size_type __size);
423// void __set_sentinel(pointer __end);
424// void __set_sentinel(size_type __size);
425//
426// void __set_capacity(size_type __capacity);
427// void __set_capacity(pointer __capacity);
428//
429// size_type __front_spare() const;
430// size_type __back_spare() const;
431//
432// reference back();
433// const_reference back() const;
434//
435// template<class _OtherLayout>
436// void __swap_without_allocator(_OtherLayout&);
437// void swap(__layout&);
438//
439// void __reset();
440// void __copy_without_alloc(__layout const&);
441// };
442//
443template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
444class __split_buffer : _Layout<__split_buffer<_Tp, _Allocator, _Layout>, _Tp, _Allocator> {
445 using __base_type _LIBCPP_NODEBUG = _Layout<__split_buffer<_Tp, _Allocator, _Layout>, _Tp, _Allocator>;
446
447public:
448 using __base_type::__back_spare;
449 using __base_type::__copy_without_alloc;
450 using __base_type::__front_cap;
451 using __base_type::__front_spare;
452 using __base_type::__get_allocator;
453 using __base_type::__raw_capacity;
454 using __base_type::__raw_sentinel;
455 using __base_type::__reset;
456 using __base_type::__set_capacity;
457 using __base_type::__set_data;
458 using __base_type::__set_sentinel;
459 using __base_type::__set_valid_range;
460
461 using typename __base_type::__alloc_traits;
462 using typename __base_type::allocator_type;
463 using typename __base_type::const_iterator;
464 using typename __base_type::const_pointer;
465 using typename __base_type::const_reference;
466 using typename __base_type::difference_type;
467 using typename __base_type::iterator;
468 using typename __base_type::pointer;
469 using typename __base_type::reference;
470 using typename __base_type::size_type;
471 using typename __base_type::value_type;
67472
68473 // A __split_buffer contains the following members which may be trivially relocatable:
69474 // - pointer: may be trivially relocatable, so it's checked
......@@ -73,36 +478,24 @@ public:
73478 __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
74479 __split_buffer,
75480 void>;
76 using __replaceable _LIBCPP_NODEBUG =
77 __conditional_t<__is_replaceable_v<pointer> && __container_allocator_is_replaceable<__alloc_traits>::value,
78 __split_buffer,
79 void>;
80
81 pointer __first_;
82 pointer __begin_;
83 pointer __end_;
84 _LIBCPP_COMPRESSED_PAIR(pointer, __cap_, allocator_type, __alloc_);
85481
86482 __split_buffer(const __split_buffer&) = delete;
87483 __split_buffer& operator=(const __split_buffer&) = delete;
88484
89 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer()
90 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
91 : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __cap_(nullptr) {}
485 _LIBCPP_HIDE_FROM_ABI __split_buffer() = default;
92486
93 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(__alloc_rr& __a)
94 : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __cap_(nullptr), __alloc_(__a) {}
487 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(allocator_type& __a) : __base_type(__a) {}
95488
96 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(const __alloc_rr& __a)
97 : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __cap_(nullptr), __alloc_(__a) {}
489 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(const allocator_type& __a)
490 : __base_type(__a) {}
98491
99492 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
100 __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a);
493 __split_buffer(size_type __cap, size_type __start, allocator_type& __a);
101494
102495 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c)
103496 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
104497
105 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c, const __alloc_rr& __a);
498 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c, const allocator_type& __a);
106499
107500 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer& operator=(__split_buffer&& __c)
108501 _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
......@@ -111,36 +504,16 @@ public:
111504
112505 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~__split_buffer();
113506
114 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __begin_; }
115 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __begin_; }
116
117 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __end_; }
118 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __end_; }
119
120 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __destruct_at_end(__begin_); }
507 using __base_type::back;
508 using __base_type::begin;
509 using __base_type::capacity;
510 using __base_type::empty;
511 using __base_type::end;
512 using __base_type::size;
121513
122 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const {
123 return static_cast<size_type>(__end_ - __begin_);
124 }
125
126 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const { return __end_ == __begin_; }
127
128 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const {
129 return static_cast<size_type>(__cap_ - __first_);
130 }
131
132 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const {
133 return static_cast<size_type>(__begin_ - __first_);
134 }
135
136 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const {
137 return static_cast<size_type>(__cap_ - __end_);
138 }
139
140 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() { return *__begin_; }
141 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const { return *__begin_; }
142 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() { return *(__end_ - 1); }
143 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const { return *(__end_ - 1); }
514 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __destruct_at_end(begin()); }
515 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() { return *begin(); }
516 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const { return *begin(); }
144517
145518 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
146519
......@@ -149,8 +522,8 @@ public:
149522 template <class... _Args>
150523 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args);
151524
152 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_front() { __destruct_at_begin(__begin_ + 1); }
153 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_back() { __destruct_at_end(__end_ - 1); }
525 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_front() { __destruct_at_begin(begin() + 1); }
526 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_back() { __destruct_at_end(end() - 1); }
154527
155528 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n);
156529 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n, const_reference __x);
......@@ -182,244 +555,242 @@ public:
182555 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT;
183556
184557 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer& __x)
185 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__alloc_rr>);
558 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>);
559
560 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const {
561 if (__front_cap() == nullptr) {
562 if (begin() != nullptr)
563 return false;
564
565 if (!empty())
566 return false;
567
568 if (capacity() != 0)
569 return false;
570
571 return true;
572 } else {
573 if (begin() < __front_cap())
574 return false;
186575
187 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
576 if (capacity() < size())
577 return false;
578
579 if (end() < begin())
580 return false;
581
582 return true;
583 }
584 }
585
586 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
587 __swap_without_allocator(__split_buffer<value_type, allocator_type, _Layout>& __other) _NOEXCEPT {
588 __base_type::__swap_without_allocator(__other);
589 }
188590
189591private:
190592 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer& __c, true_type)
191593 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
192 __alloc_ = std::move(__c.__alloc_);
594 __get_allocator() = std::move(__c.__get_allocator());
193595 }
194596
195597 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT {}
196598
197599 struct _ConstructTransaction {
198600 _LIBCPP_CONSTEXPR_SINCE_CXX20
199 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction(pointer* __p, size_type __n) _NOEXCEPT
200 : __pos_(*__p),
201 __end_(*__p + __n),
202 __dest_(__p) {}
601 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction(__split_buffer* __parent, pointer __p, size_type __n) _NOEXCEPT
602 : __pos_(__p),
603 __end_(__p + __n),
604 __parent_(__parent) {}
203605
204 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { *__dest_ = __pos_; }
606 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { __parent_->__set_sentinel(__pos_); }
205607
206608 pointer __pos_;
207609 const pointer __end_;
208610
209611 private:
210 pointer* __dest_;
612 __split_buffer* __parent_;
211613 };
212};
213614
214template <class _Tp, class _Allocator>
215_LIBCPP_CONSTEXPR_SINCE_CXX20 bool __split_buffer<_Tp, _Allocator>::__invariants() const {
216 if (__first_ == nullptr) {
217 if (__begin_ != nullptr)
218 return false;
219 if (__end_ != nullptr)
220 return false;
221 if (__cap_ != nullptr)
222 return false;
223 } else {
224 if (__begin_ < __first_)
225 return false;
226 if (__end_ < __begin_)
227 return false;
228 if (__cap_ < __end_)
229 return false;
230 }
231 return true;
232}
615 template <class _T2, class _A2, template <class, class, class> class _L2>
616 friend class __split_buffer;
617};
233618
234// Default constructs __n objects starting at __end_
619// Default constructs __n objects starting at `end()`
235620// throws if construction throws
236621// Precondition: __n > 0
237622// Precondition: size() + __n <= capacity()
238623// Postcondition: size() == size() + __n
239template <class _Tp, class _Allocator>
240_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n) {
241 _ConstructTransaction __tx(std::addressof(this->__end_), __n);
624template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
625_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator, _Layout>::__construct_at_end(size_type __n) {
626 _ConstructTransaction __tx(this, end(), __n);
242627 for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
243 __alloc_traits::construct(__alloc_, std::__to_address(__tx.__pos_));
628 __alloc_traits::construct(__get_allocator(), std::__to_address(__tx.__pos_));
244629 }
245630}
246631
247// Copy constructs __n objects starting at __end_ from __x
632// Copy constructs __n objects starting at `end()` from __x
248633// throws if construction throws
249634// Precondition: __n > 0
250635// Precondition: size() + __n <= capacity()
251636// Postcondition: size() == old size() + __n
252637// Postcondition: [i] == __x for all i in [size() - __n, __n)
253template <class _Tp, class _Allocator>
638template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
254639_LIBCPP_CONSTEXPR_SINCE_CXX20 void
255__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) {
256 _ConstructTransaction __tx(std::addressof(this->__end_), __n);
640__split_buffer<_Tp, _Allocator, _Layout>::__construct_at_end(size_type __n, const_reference __x) {
641 _ConstructTransaction __tx(this, end(), __n);
257642 for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
258 __alloc_traits::construct(__alloc_, std::__to_address(__tx.__pos_), __x);
643 __alloc_traits::construct(__get_allocator(), std::__to_address(__tx.__pos_), __x);
259644 }
260645}
261646
262template <class _Tp, class _Allocator>
647template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
263648template <class _Iterator, class _Sentinel>
264649_LIBCPP_CONSTEXPR_SINCE_CXX20 void
265__split_buffer<_Tp, _Allocator>::__construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last) {
266 __alloc_rr& __a = __alloc_;
650__split_buffer<_Tp, _Allocator, _Layout>::__construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last) {
651 allocator_type& __a = __get_allocator();
267652 for (; __first != __last; ++__first) {
268 if (__end_ == __cap_) {
269 size_type __old_cap = __cap_ - __first_;
653 if (__back_spare() == 0) {
654 size_type __old_cap = capacity();
270655 size_type __new_cap = std::max<size_type>(2 * __old_cap, 8);
271656 __split_buffer __buf(__new_cap, 0, __a);
272 for (pointer __p = __begin_; __p != __end_; ++__p, (void)++__buf.__end_)
273 __alloc_traits::construct(__buf.__alloc_, std::__to_address(__buf.__end_), std::move(*__p));
657 pointer __buf_end = __buf.end();
658 pointer __end = end();
659 for (pointer __p = begin(); __p != __end; ++__p) {
660 __alloc_traits::construct(__buf.__get_allocator(), std::__to_address(__buf_end), std::move(*__p));
661 __buf.__set_sentinel(++__buf_end);
662 }
274663 swap(__buf);
275664 }
276 __alloc_traits::construct(__a, std::__to_address(this->__end_), *__first);
277 ++this->__end_;
665
666 __alloc_traits::construct(__a, std::__to_address(end()), *__first);
667 __set_sentinel(size() + 1);
278668 }
279669}
280template <class _Tp, class _Allocator>
670
671template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
281672template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
282673_LIBCPP_CONSTEXPR_SINCE_CXX20 void
283__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) {
674__split_buffer<_Tp, _Allocator, _Layout>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) {
284675 __construct_at_end_with_size(__first, std::distance(__first, __last));
285676}
286677
287template <class _Tp, class _Allocator>
678template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
288679template <class _ForwardIterator>
289680_LIBCPP_CONSTEXPR_SINCE_CXX20 void
290__split_buffer<_Tp, _Allocator>::__construct_at_end_with_size(_ForwardIterator __first, size_type __n) {
291 _ConstructTransaction __tx(std::addressof(this->__end_), __n);
681__split_buffer<_Tp, _Allocator, _Layout>::__construct_at_end_with_size(_ForwardIterator __first, size_type __n) {
682 _ConstructTransaction __tx(this, end(), __n);
292683 for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__first) {
293 __alloc_traits::construct(__alloc_, std::__to_address(__tx.__pos_), *__first);
684 __alloc_traits::construct(__get_allocator(), std::__to_address(__tx.__pos_), *__first);
294685 }
295686}
296687
297template <class _Tp, class _Allocator>
688template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
298689_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
299__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type) {
300 while (__begin_ != __new_begin)
301 __alloc_traits::destroy(__alloc_, std::__to_address(__begin_++));
690__split_buffer<_Tp, _Allocator, _Layout>::__destruct_at_begin(pointer __new_begin, false_type) {
691 pointer __begin = begin();
692 // Updating begin at every iteration is unnecessary because destruction can't throw.
693 while (__begin != __new_begin)
694 __alloc_traits::destroy(__get_allocator(), std::__to_address(__begin++));
695 __set_valid_range(__begin, end());
302696}
303697
304template <class _Tp, class _Allocator>
698template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
305699_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
306__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type) {
307 __begin_ = __new_begin;
308}
309
310template <class _Tp, class _Allocator>
311_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
312__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT {
313 while (__new_last != __end_)
314 __alloc_traits::destroy(__alloc_, std::__to_address(--__end_));
700__split_buffer<_Tp, _Allocator, _Layout>::__destruct_at_begin(pointer __new_begin, true_type) {
701 __set_valid_range(__new_begin, end());
315702}
316703
317template <class _Tp, class _Allocator>
704template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
318705_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
319__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT {
320 __end_ = __new_last;
706__split_buffer<_Tp, _Allocator, _Layout>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT {
707 pointer __end = end();
708 // Updating begin at every iteration is unnecessary because destruction can't throw.
709 while (__new_last != __end)
710 __alloc_traits::destroy(__get_allocator(), std::__to_address(--__end));
711 __set_sentinel(__end);
321712}
322713
323template <class _Tp, class _Allocator>
714template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
324715_LIBCPP_CONSTEXPR_SINCE_CXX20
325__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a)
326 : __cap_(nullptr), __alloc_(__a) {
327 if (__cap == 0) {
328 __first_ = nullptr;
329 } else {
330 auto __allocation = std::__allocate_at_least(__alloc_, __cap);
331 __first_ = __allocation.ptr;
332 __cap = __allocation.count;
716__split_buffer<_Tp, _Allocator, _Layout>::__split_buffer(size_type __cap, size_type __start, allocator_type& __a)
717 : __base_type(__a) {
718 _LIBCPP_ASSERT_INTERNAL(__cap >= __start, "can't have a start point outside the capacity");
719 if (__cap > 0) {
720 auto __allocation = std::__allocate_at_least(__get_allocator(), __cap);
721 __set_data(__allocation.ptr);
722 __cap = __allocation.count;
333723 }
334 __begin_ = __end_ = __first_ + __start;
335 __cap_ = __first_ + __cap;
724
725 pointer __begin = __front_cap() + __start;
726 __set_valid_range(__begin, __begin);
727 __set_capacity(__cap);
336728}
337729
338template <class _Tp, class _Allocator>
339_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator>::~__split_buffer() {
730template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
731_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator, _Layout>::~__split_buffer() {
340732 clear();
341 if (__first_)
342 __alloc_traits::deallocate(__alloc_, __first_, capacity());
733 if (__front_cap())
734 __alloc_traits::deallocate(__get_allocator(), __front_cap(), capacity());
343735}
344736
345template <class _Tp, class _Allocator>
346_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c)
737template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
738_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator, _Layout>::__split_buffer(__split_buffer&& __c)
347739 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
348 : __first_(std::move(__c.__first_)),
349 __begin_(std::move(__c.__begin_)),
350 __end_(std::move(__c.__end_)),
351 __cap_(std::move(__c.__cap_)),
352 __alloc_(std::move(__c.__alloc_)) {
353 __c.__first_ = nullptr;
354 __c.__begin_ = nullptr;
355 __c.__end_ = nullptr;
356 __c.__cap_ = nullptr;
740 : __base_type(std::move(__c)) {
741 __c.__reset();
357742}
358743
359template <class _Tp, class _Allocator>
744template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
360745_LIBCPP_CONSTEXPR_SINCE_CXX20
361__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a)
362 : __cap_(nullptr), __alloc_(__a) {
363 if (__a == __c.__alloc_) {
364 __first_ = __c.__first_;
365 __begin_ = __c.__begin_;
366 __end_ = __c.__end_;
367 __cap_ = __c.__cap_;
368 __c.__first_ = nullptr;
369 __c.__begin_ = nullptr;
370 __c.__end_ = nullptr;
371 __c.__cap_ = nullptr;
746__split_buffer<_Tp, _Allocator, _Layout>::__split_buffer(__split_buffer&& __c, const allocator_type& __a)
747 : __base_type(__a) {
748 if (__a == __c.__get_allocator()) {
749 __set_data(__c.__front_cap());
750 __set_valid_range(__c.begin(), __c.end());
751 __set_capacity(__c.capacity());
752 __c.__reset();
372753 } else {
373 auto __allocation = std::__allocate_at_least(__alloc_, __c.size());
374 __first_ = __allocation.ptr;
375 __begin_ = __end_ = __first_;
376 __cap_ = __first_ + __allocation.count;
754 auto __allocation = std::__allocate_at_least(__get_allocator(), __c.size());
755 __set_data(__allocation.ptr);
756 __set_valid_range(__front_cap(), __front_cap());
757 __set_capacity(__allocation.count);
377758 typedef move_iterator<iterator> _Ip;
378759 __construct_at_end(_Ip(__c.begin()), _Ip(__c.end()));
379760 }
380761}
381762
382template <class _Tp, class _Allocator>
383_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator>&
384__split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c)
763template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
764_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator, _Layout>&
765__split_buffer<_Tp, _Allocator, _Layout>::operator=(__split_buffer&& __c)
385766 _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
386767 is_nothrow_move_assignable<allocator_type>::value) ||
387768 !__alloc_traits::propagate_on_container_move_assignment::value) {
388769 clear();
389770 shrink_to_fit();
390 __first_ = __c.__first_;
391 __begin_ = __c.__begin_;
392 __end_ = __c.__end_;
393 __cap_ = __c.__cap_;
771 __copy_without_alloc(__c);
394772 __move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
395 __c.__first_ = __c.__begin_ = __c.__end_ = __c.__cap_ = nullptr;
773 __c.__reset();
396774 return *this;
397775}
398776
399template <class _Tp, class _Allocator>
400_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x)
401 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__alloc_rr>) {
402 std::swap(__first_, __x.__first_);
403 std::swap(__begin_, __x.__begin_);
404 std::swap(__end_, __x.__end_);
405 std::swap(__cap_, __x.__cap_);
406 std::__swap_allocator(__alloc_, __x.__alloc_);
777template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
778_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator, _Layout>::swap(__split_buffer& __x)
779 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>) {
780 __base_type::swap(__x);
407781}
408782
409template <class _Tp, class _Allocator>
410_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT {
783template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
784_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator, _Layout>::shrink_to_fit() _NOEXCEPT {
411785 if (capacity() > size()) {
412786#if _LIBCPP_HAS_EXCEPTIONS
413787 try {
414788#endif // _LIBCPP_HAS_EXCEPTIONS
415 __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc_);
789 __split_buffer<value_type, allocator_type, _Layout> __t(size(), 0, __get_allocator());
416790 if (__t.capacity() < capacity()) {
417 __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
418 __t.__end_ = __t.__begin_ + (__end_ - __begin_);
419 std::swap(__first_, __t.__first_);
420 std::swap(__begin_, __t.__begin_);
421 std::swap(__end_, __t.__end_);
422 std::swap(__cap_, __t.__cap_);
791 __t.__construct_at_end(move_iterator<pointer>(begin()), move_iterator<pointer>(end()));
792 __t.__set_sentinel(size());
793 __swap_without_allocator(__t);
423794 }
424795#if _LIBCPP_HAS_EXCEPTIONS
425796 } catch (...) {
......@@ -428,55 +799,56 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::shrink_to_fi
428799 }
429800}
430801
431template <class _Tp, class _Allocator>
802template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
432803template <class... _Args>
433_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::emplace_front(_Args&&... __args) {
434 if (__begin_ == __first_) {
435 if (__end_ < __cap_) {
436 difference_type __d = __cap_ - __end_;
804_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator, _Layout>::emplace_front(_Args&&... __args) {
805 if (__front_spare() == 0) {
806 pointer __end = end();
807 if (__back_spare() > 0) {
808 // The elements are pressed up against the front of the buffer: we need to move them back a
809 // little bit to make `emplace_front` have amortised O(1) complexity.
810 difference_type __d = __back_spare();
437811 __d = (__d + 1) / 2;
438 __begin_ = std::move_backward(__begin_, __end_, __end_ + __d);
439 __end_ += __d;
812 auto __new_end = __end + __d;
813 __set_valid_range(std::move_backward(begin(), __end, __new_end), __new_end);
440814 } else {
441 size_type __c = std::max<size_type>(2 * static_cast<size_type>(__cap_ - __first_), 1);
442 __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc_);
443 __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
444 std::swap(__first_, __t.__first_);
445 std::swap(__begin_, __t.__begin_);
446 std::swap(__end_, __t.__end_);
447 std::swap(__cap_, __t.__cap_);
815 size_type __c = std::max<size_type>(2 * capacity(), 1);
816 __split_buffer<value_type, allocator_type, _Layout> __t(__c, (__c + 3) / 4, __get_allocator());
817 __t.__construct_at_end(move_iterator<pointer>(begin()), move_iterator<pointer>(__end));
818 __base_type::__swap_without_allocator(__t);
448819 }
449820 }
450 __alloc_traits::construct(__alloc_, std::__to_address(__begin_ - 1), std::forward<_Args>(__args)...);
451 --__begin_;
821
822 __alloc_traits::construct(__get_allocator(), std::__to_address(begin() - 1), std::forward<_Args>(__args)...);
823 __set_valid_range(begin() - 1, size() + 1);
452824}
453825
454template <class _Tp, class _Allocator>
826template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
455827template <class... _Args>
456_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args) {
457 if (__end_ == __cap_) {
458 if (__begin_ > __first_) {
459 difference_type __d = __begin_ - __first_;
828_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator, _Layout>::emplace_back(_Args&&... __args) {
829 pointer __end = end();
830 if (__back_spare() == 0) {
831 if (__front_spare() > 0) {
832 difference_type __d = __front_spare();
460833 __d = (__d + 1) / 2;
461 __end_ = std::move(__begin_, __end_, __begin_ - __d);
462 __begin_ -= __d;
834 __end = std::move(begin(), __end, begin() - __d);
835 __set_valid_range(begin() - __d, __end);
463836 } else {
464 size_type __c = std::max<size_type>(2 * static_cast<size_type>(__cap_ - __first_), 1);
465 __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc_);
466 __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
467 std::swap(__first_, __t.__first_);
468 std::swap(__begin_, __t.__begin_);
469 std::swap(__end_, __t.__end_);
470 std::swap(__cap_, __t.__cap_);
837 size_type __c = std::max<size_type>(2 * capacity(), 1);
838 __split_buffer<value_type, allocator_type, _Layout> __t(__c, __c / 4, __get_allocator());
839 __t.__construct_at_end(move_iterator<pointer>(begin()), move_iterator<pointer>(__end));
840 __base_type::__swap_without_allocator(__t);
471841 }
472842 }
473 __alloc_traits::construct(__alloc_, std::__to_address(__end_), std::forward<_Args>(__args)...);
474 ++__end_;
843
844 __alloc_traits::construct(__get_allocator(), std::__to_address(__end), std::forward<_Args>(__args)...);
845 __set_sentinel(++__end);
475846}
476847
477template <class _Tp, class _Allocator>
848template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
478849_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
479swap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
850swap(__split_buffer<_Tp, _Allocator, _Layout>& __x, __split_buffer<_Tp, _Allocator, _Layout>& __y)
851 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
480852 __x.swap(__y);
481853}
482854
lib/libcxx/include/__stop_token/atomic_unique_lock.h+1-1
......@@ -27,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2727// where State contains a lock bit and might contain other data,
2828// and LockedBit is the value of State when the lock bit is set, e.g 1 << 2
2929template <class _State, _State _LockedBit>
30class _LIBCPP_AVAILABILITY_SYNC __atomic_unique_lock {
30class __atomic_unique_lock {
3131 static_assert(std::__popcount(static_cast<unsigned long long>(_LockedBit)) == 1,
3232 "LockedBit must be an integer where only one bit is set");
3333
lib/libcxx/include/__stop_token/stop_callback.h+2-2
......@@ -34,7 +34,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3434#if _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_THREADS
3535
3636template <class _Callback>
37class _LIBCPP_AVAILABILITY_SYNC stop_callback : private __stop_callback_base {
37class stop_callback : private __stop_callback_base {
3838 static_assert(invocable<_Callback>,
3939 "Mandates: stop_callback is instantiated with an argument for the template parameter Callback that "
4040 "satisfies invocable.");
......@@ -91,7 +91,7 @@ private:
9191};
9292
9393template <class _Callback>
94_LIBCPP_AVAILABILITY_SYNC stop_callback(stop_token, _Callback) -> stop_callback<_Callback>;
94stop_callback(stop_token, _Callback) -> stop_callback<_Callback>;
9595
9696#endif // _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_THREADS
9797
lib/libcxx/include/__stop_token/stop_source.h+1-1
......@@ -30,7 +30,7 @@ struct nostopstate_t {
3030
3131inline constexpr nostopstate_t nostopstate{};
3232
33class _LIBCPP_AVAILABILITY_SYNC stop_source {
33class stop_source {
3434public:
3535 _LIBCPP_HIDE_FROM_ABI stop_source() : __state_(new __stop_state()) { __state_->__increment_stop_source_counter(); }
3636
lib/libcxx/include/__stop_token/stop_state.h+4-4
......@@ -100,7 +100,7 @@ public:
100100 return ((__curent_state & __stop_requested_bit) != 0) || ((__curent_state >> __stop_source_counter_shift) != 0);
101101 }
102102
103 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __request_stop() noexcept {
103 _LIBCPP_HIDE_FROM_ABI bool __request_stop() noexcept {
104104 auto __cb_list_lock = __try_lock_for_request_stop();
105105 if (!__cb_list_lock.__owns_lock()) {
106106 return false;
......@@ -137,7 +137,7 @@ public:
137137 return true;
138138 }
139139
140 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __add_callback(__stop_callback_base* __cb) noexcept {
140 _LIBCPP_HIDE_FROM_ABI bool __add_callback(__stop_callback_base* __cb) noexcept {
141141 // If it is already stop_requested. Do not try to request it again.
142142 const auto __give_up_trying_to_lock_condition = [__cb](__state_t __state) {
143143 if ((__state & __stop_requested_bit) != 0) {
......@@ -164,7 +164,7 @@ public:
164164 }
165165
166166 // called by the destructor of stop_callback
167 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void __remove_callback(__stop_callback_base* __cb) noexcept {
167 _LIBCPP_HIDE_FROM_ABI void __remove_callback(__stop_callback_base* __cb) noexcept {
168168 __callback_list_lock __cb_list_lock(__state_);
169169
170170 // under below condition, the request_stop call just popped __cb from the list and could execute it now
......@@ -192,7 +192,7 @@ public:
192192 }
193193
194194private:
195 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI __callback_list_lock __try_lock_for_request_stop() noexcept {
195 _LIBCPP_HIDE_FROM_ABI __callback_list_lock __try_lock_for_request_stop() noexcept {
196196 // If it is already stop_requested, do not try to request stop or lock the list again.
197197 const auto __lock_fail_condition = [](__state_t __state) { return (__state & __stop_requested_bit) != 0; };
198198
lib/libcxx/include/__stop_token/stop_token.h+1-1
......@@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222
2323#if _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_THREADS
2424
25class _LIBCPP_AVAILABILITY_SYNC stop_token {
25class stop_token {
2626public:
2727 _LIBCPP_HIDE_FROM_ABI stop_token() noexcept = default;
2828
lib/libcxx/include/__string/char_traits.h+51-31
......@@ -94,16 +94,17 @@ struct char_traits<char> {
9494 }
9595
9696 // TODO: Make this _LIBCPP_HIDE_FROM_ABI
97 static inline _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT {
97 [[__nodiscard__]] static inline _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT {
9898 return __c1 == __c2;
9999 }
100 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT {
100 [[__nodiscard__]] static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
101 lt(char_type __c1, char_type __c2) _NOEXCEPT {
101102 return (unsigned char)__c1 < (unsigned char)__c2;
102103 }
103104
104105 // __constexpr_memcmp requires a trivially lexicographically comparable type, but char is not when char is a signed
105106 // type
106 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
107 [[__nodiscard__]] static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
107108 compare(const char_type* __lhs, const char_type* __rhs, size_t __count) _NOEXCEPT {
108109 if (__libcpp_is_constant_evaluated()) {
109110#ifdef _LIBCPP_COMPILER_CLANG_BASED
......@@ -126,11 +127,12 @@ struct char_traits<char> {
126127 }
127128 }
128129
129 static inline _LIBCPP_HIDE_FROM_ABI size_t _LIBCPP_CONSTEXPR_SINCE_CXX17 length(const char_type* __s) _NOEXCEPT {
130 [[__nodiscard__]] static inline _LIBCPP_HIDE_FROM_ABI size_t _LIBCPP_CONSTEXPR_SINCE_CXX17
131 length(const char_type* __s) _NOEXCEPT {
130132 return std::__constexpr_strlen(__s);
131133 }
132134
133 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
135 [[__nodiscard__]] static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
134136 find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
135137 return std::__constexpr_memchr(__s, __a, __n);
136138 }
......@@ -154,19 +156,24 @@ struct char_traits<char> {
154156 return __s;
155157 }
156158
157 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
159 [[__nodiscard__]] static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
158160 return eq_int_type(__c, eof()) ? ~eof() : __c;
159161 }
160 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {
162 [[__nodiscard__]] static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type
163 to_char_type(int_type __c) _NOEXCEPT {
161164 return char_type(__c);
162165 }
163 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT {
166 [[__nodiscard__]] static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type
167 to_int_type(char_type __c) _NOEXCEPT {
164168 return int_type((unsigned char)__c);
165169 }
166 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {
170 [[__nodiscard__]] static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
171 eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {
167172 return __c1 == __c2;
168173 }
169 static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return int_type(EOF); }
174 [[__nodiscard__]] static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT {
175 return int_type(EOF);
176 }
170177};
171178
172179template <class _CharT, class _IntT, _IntT _EOFVal>
......@@ -187,11 +194,11 @@ struct __char_traits_base {
187194 __lhs = __rhs;
188195 }
189196
190 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool eq(char_type __lhs, char_type __rhs) _NOEXCEPT {
197 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool eq(char_type __lhs, char_type __rhs) _NOEXCEPT {
191198 return __lhs == __rhs;
192199 }
193200
194 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool lt(char_type __lhs, char_type __rhs) _NOEXCEPT {
201 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool lt(char_type __lhs, char_type __rhs) _NOEXCEPT {
195202 return __lhs < __rhs;
196203 }
197204
......@@ -213,19 +220,22 @@ struct __char_traits_base {
213220 return __str;
214221 }
215222
216 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {
223 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {
217224 return char_type(__c);
218225 }
219226
220 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT { return int_type(__c); }
227 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT {
228 return int_type(__c);
229 }
221230
222 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __lhs, int_type __rhs) _NOEXCEPT {
231 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool
232 eq_int_type(int_type __lhs, int_type __rhs) _NOEXCEPT {
223233 return __lhs == __rhs;
224234 }
225235
226 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return _EOFVal; }
236 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return _EOFVal; }
227237
228 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
238 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
229239 return eq_int_type(__c, eof()) ? static_cast<int_type>(~eof()) : __c;
230240 }
231241};
......@@ -235,18 +245,19 @@ struct __char_traits_base {
235245#if _LIBCPP_HAS_WIDE_CHARACTERS
236246template <>
237247struct char_traits<wchar_t> : __char_traits_base<wchar_t, wint_t, static_cast<wint_t>(WEOF)> {
238 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
248 [[__nodiscard__]] static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
239249 compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
240250 if (__n == 0)
241251 return 0;
242252 return std::__constexpr_wmemcmp(__s1, __s2, __n);
243253 }
244254
245 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT {
255 [[__nodiscard__]] static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t
256 length(const char_type* __s) _NOEXCEPT {
246257 return std::__constexpr_wcslen(__s);
247258 }
248259
249 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
260 [[__nodiscard__]] static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
250261 find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
251262 return std::__constexpr_wmemchr(__s, __a, __n);
252263 }
......@@ -257,16 +268,16 @@ struct char_traits<wchar_t> : __char_traits_base<wchar_t, wint_t, static_cast<wi
257268
258269template <>
259270struct char_traits<char8_t> : __char_traits_base<char8_t, unsigned int, static_cast<unsigned int>(EOF)> {
260 static _LIBCPP_HIDE_FROM_ABI constexpr int
271 [[nodiscard]] static _LIBCPP_HIDE_FROM_ABI constexpr int
261272 compare(const char_type* __s1, const char_type* __s2, size_t __n) noexcept {
262273 return std::__constexpr_memcmp(__s1, __s2, __element_count(__n));
263274 }
264275
265 static _LIBCPP_HIDE_FROM_ABI constexpr size_t length(const char_type* __str) noexcept {
276 [[nodiscard]] static _LIBCPP_HIDE_FROM_ABI constexpr size_t length(const char_type* __str) noexcept {
266277 return std::__constexpr_strlen(__str);
267278 }
268279
269 _LIBCPP_HIDE_FROM_ABI static constexpr const char_type*
280 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr const char_type*
270281 find(const char_type* __s, size_t __n, const char_type& __a) noexcept {
271282 return std::__constexpr_memchr(__s, __a, __n);
272283 }
......@@ -276,11 +287,11 @@ struct char_traits<char8_t> : __char_traits_base<char8_t, unsigned int, static_c
276287
277288template <>
278289struct char_traits<char16_t> : __char_traits_base<char16_t, uint_least16_t, static_cast<uint_least16_t>(0xFFFF)> {
279 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 int
290 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 int
280291 compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
281292 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT;
282293
283 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
294 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
284295 find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
285296 __identity __proj;
286297 const char_type* __match = std::__find(__s, __s + __n, __a, __proj);
......@@ -290,7 +301,7 @@ struct char_traits<char16_t> : __char_traits_base<char16_t, uint_least16_t, stat
290301 }
291302};
292303
293inline _LIBCPP_CONSTEXPR_SINCE_CXX17 int
304[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX17 int
294305char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
295306 for (; __n; --__n, ++__s1, ++__s2) {
296307 if (lt(*__s1, *__s2))
......@@ -301,7 +312,8 @@ char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, siz
301312 return 0;
302313}
303314
304inline _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT {
315[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t
316char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT {
305317 size_t __len = 0;
306318 for (; !eq(*__s, char_type(0)); ++__s)
307319 ++__len;
......@@ -310,11 +322,11 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t char_traits<char16_t>::length(const
310322
311323template <>
312324struct char_traits<char32_t> : __char_traits_base<char32_t, uint_least32_t, static_cast<uint_least32_t>(0xFFFFFFFF)> {
313 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 int
325 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 int
314326 compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
315327 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT;
316328
317 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
329 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
318330 find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
319331 __identity __proj;
320332 const char_type* __match = std::__find(__s, __s + __n, __a, __proj);
......@@ -324,7 +336,7 @@ struct char_traits<char32_t> : __char_traits_base<char32_t, uint_least32_t, stat
324336 }
325337};
326338
327inline _LIBCPP_CONSTEXPR_SINCE_CXX17 int
339[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX17 int
328340char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
329341 for (; __n; --__n, ++__s1, ++__s2) {
330342 if (lt(*__s1, *__s2))
......@@ -335,7 +347,8 @@ char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, siz
335347 return 0;
336348}
337349
338inline _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT {
350[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t
351char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT {
339352 size_t __len = 0;
340353 for (; !eq(*__s, char_type(0)); ++__s)
341354 ++__len;
......@@ -369,6 +382,13 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 const _CharT* __searc
369382 if (__len1 < __len2)
370383 return __last1;
371384
385 if (__builtin_constant_p(__len2 == 1) && __len2 == 1) {
386 auto __res = _Traits::find(__first1, __len1, *__first2);
387 if (__res == nullptr)
388 return __last1;
389 return __res;
390 }
391
372392 // First element of __first2 is loop invariant.
373393 _CharT __f2 = *__first2;
374394 while (true) {
lib/libcxx/include/__string/constexpr_c_functions.h+5-5
......@@ -22,7 +22,6 @@
2222#include <__type_traits/is_equality_comparable.h>
2323#include <__type_traits/is_integral.h>
2424#include <__type_traits/is_same.h>
25#include <__type_traits/is_trivially_copyable.h>
2625#include <__type_traits/is_trivially_lexicographically_comparable.h>
2726#include <__type_traits/remove_cv.h>
2827#include <__utility/element_count.h>
......@@ -96,14 +95,13 @@ __constexpr_memcmp(const _Tp* __lhs, const _Up* __rhs, __element_count __n) {
9695 }
9796}
9897
99// Because of __libcpp_is_trivially_equality_comparable we know that comparing the object representations is equivalent
98// Because of __is_trivially_equality_comparable_v we know that comparing the object representations is equivalent
10099// to a std::memcmp(...) == 0. Since we have multiple objects contiguously in memory, we can call memcmp once instead
101100// of invoking it on every object individually.
102101template <class _Tp, class _Up>
103102_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
104103__constexpr_memcmp_equal(const _Tp* __lhs, const _Up* __rhs, __element_count __n) {
105 static_assert(__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
106 "_Tp and _Up have to be trivially equality comparable");
104 static_assert(__is_trivially_equality_comparable_v<_Tp, _Up>, "_Tp and _Up have to be trivially equality comparable");
107105
108106 auto __count = static_cast<size_t>(__n);
109107
......@@ -128,7 +126,7 @@ __constexpr_memcmp_equal(const _Tp* __lhs, const _Up* __rhs, __element_count __n
128126
129127template <class _Tp, class _Up>
130128_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __constexpr_memchr(_Tp* __str, _Up __value, size_t __count) {
131 static_assert(sizeof(_Tp) == 1 && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
129 static_assert(sizeof(_Tp) == 1 && __is_trivially_equality_comparable_v<_Tp, _Up>,
132130 "Calling memchr on non-trivially equality comparable types is unsafe.");
133131
134132 if (__libcpp_is_constant_evaluated()) {
......@@ -225,6 +223,8 @@ __constexpr_memmove(_Tp* __dest, _Up* __src, __element_count __n) {
225223 std::__assign_trivially_copyable(__dest[__i], __src[__i]);
226224 }
227225 }
226 } else if _LIBCPP_CONSTEXPR (sizeof(_Tp) == __datasizeof_v<_Tp>) {
227 ::__builtin_memmove(__dest, __src, __count * sizeof(_Tp));
228228 } else if (__count > 0) {
229229 ::__builtin_memmove(__dest, __src, (__count - 1) * sizeof(_Tp) + __datasizeof_v<_Tp>);
230230 }
lib/libcxx/include/__support/xlocale/__strtonum_fallback.h-8
......@@ -34,12 +34,4 @@ inline _LIBCPP_HIDE_FROM_ABI long double strtold_l(const char* __nptr, char** __
3434 return ::strtold(__nptr, __endptr);
3535}
3636
37inline _LIBCPP_HIDE_FROM_ABI long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t) {
38 return ::strtoll(__nptr, __endptr, __base);
39}
40
41inline _LIBCPP_HIDE_FROM_ABI unsigned long long strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t) {
42 return ::strtoull(__nptr, __endptr, __base);
43}
44
4537#endif // _LIBCPP___SUPPORT_XLOCALE_STRTONUM_FALLBACK_H
lib/libcxx/include/__system_error/error_category.h+8-8
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23class _LIBCPP_EXPORTED_FROM_ABI error_condition;
23class error_condition;
2424class _LIBCPP_EXPORTED_FROM_ABI error_code;
2525
2626class _LIBCPP_HIDDEN __do_message;
......@@ -37,11 +37,11 @@ public:
3737 error_category(const error_category&) = delete;
3838 error_category& operator=(const error_category&) = delete;
3939
40 virtual const char* name() const _NOEXCEPT = 0;
41 virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;
42 virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;
43 virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;
44 virtual string message(int __ev) const = 0;
40 [[__nodiscard__]] virtual const char* name() const _NOEXCEPT = 0;
41 [[__nodiscard__]] virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;
42 [[__nodiscard__]] virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;
43 [[__nodiscard__]] virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;
44 [[__nodiscard__]] virtual string message(int __ev) const = 0;
4545
4646 _LIBCPP_HIDE_FROM_ABI bool operator==(const error_category& __rhs) const _NOEXCEPT { return this == &__rhs; }
4747
......@@ -67,8 +67,8 @@ public:
6767 string message(int __ev) const override;
6868};
6969
70[[__gnu__::__const__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& generic_category() _NOEXCEPT;
71[[__gnu__::__const__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& system_category() _NOEXCEPT;
70[[__gnu__::__const__]] [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& generic_category() _NOEXCEPT;
71[[__gnu__::__const__]] [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& system_category() _NOEXCEPT;
7272
7373_LIBCPP_END_NAMESPACE_STD
7474
lib/libcxx/include/__system_error/error_code.h+5-5
......@@ -71,20 +71,20 @@ public:
7171 __cat_ = &system_category();
7272 }
7373
74 _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
74 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
7575
76 _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
76 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
7777
78 _LIBCPP_HIDE_FROM_ABI error_condition default_error_condition() const _NOEXCEPT {
78 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI error_condition default_error_condition() const _NOEXCEPT {
7979 return __cat_->default_error_condition(__val_);
8080 }
8181
82 string message() const;
82 [[__nodiscard__]] string message() const;
8383
8484 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; }
8585};
8686
87inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(errc __e) _NOEXCEPT {
87[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(errc __e) _NOEXCEPT {
8888 return error_code(static_cast<int>(__e), generic_category());
8989}
9090
lib/libcxx/include/__system_error/error_condition.h+4-4
......@@ -80,15 +80,15 @@ public:
8080 __cat_ = &generic_category();
8181 }
8282
83 _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
83 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
8484
85 _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
86 string message() const;
85 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
86 [[__nodiscard__]] string message() const;
8787
8888 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; }
8989};
9090
91inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(errc __e) _NOEXCEPT {
91[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(errc __e) _NOEXCEPT {
9292 return error_condition(static_cast<int>(__e), generic_category());
9393}
9494
lib/libcxx/include/__system_error/system_error.h+1-1
......@@ -36,7 +36,7 @@ public:
3636 _LIBCPP_HIDE_FROM_ABI system_error(const system_error&) _NOEXCEPT = default;
3737 ~system_error() _NOEXCEPT override;
3838
39 _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
39 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
4040};
4141
4242// __ev is expected to be an error in the generic_category domain (e.g. from
lib/libcxx/include/__thread/id.h+1-1
......@@ -23,7 +23,7 @@
2323_LIBCPP_BEGIN_NAMESPACE_STD
2424
2525#if _LIBCPP_HAS_THREADS
26class _LIBCPP_EXPORTED_FROM_ABI __thread_id;
26class __thread_id;
2727
2828namespace this_thread {
2929
lib/libcxx/include/__thread/jthread.h+1-1
......@@ -36,7 +36,7 @@ _LIBCPP_PUSH_MACROS
3636
3737_LIBCPP_BEGIN_NAMESPACE_STD
3838
39class _LIBCPP_AVAILABILITY_SYNC jthread {
39class jthread {
4040public:
4141 // types
4242 using id = thread::id;
lib/libcxx/include/__thread/poll_with_backoff.h+27-8
......@@ -22,33 +22,50 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222
2323static _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64;
2424
25enum class __backoff_results : unsigned char {
26 __continue_poll = 1,
27 __poll_success = 2,
28 __timeout = 3,
29 __backoff_failure = 4,
30};
31
32enum class __poll_with_backoff_results : unsigned char {
33 __poll_success = static_cast<unsigned char>(__backoff_results::__poll_success),
34 __timeout = static_cast<unsigned char>(__backoff_results::__timeout),
35 __backoff_failure = static_cast<unsigned char>(__backoff_results::__backoff_failure),
36};
37
2538// Polls a thread for a condition given by a predicate, and backs off based on a backoff policy
2639// before polling again.
2740//
2841// - __poll is the "test function" that should return true if polling succeeded, and false if it failed.
2942//
3043// - __backoff is the "backoff policy", which is called with the duration since we started polling. It should
31// return false in order to resume polling, and true if polling should stop entirely for some reason.
44// return __backoff_results::__continue_poll in order to resume polling, and other appropriate __backoff_results
45// if polling should stop entirely for some reason.
3246// In general, backoff policies sleep for some time before returning control to the polling loop.
3347//
3448// - __max_elapsed is the maximum duration to try polling for. If the maximum duration is exceeded,
35// the polling loop will return false to report a timeout.
49// the polling loop will return __poll_with_backoff_results::__timeout to report a timeout.
50
3651template <class _Poll, class _Backoff>
37_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_poll_with_backoff(
52_LIBCPP_HIDE_FROM_ABI __poll_with_backoff_results __libcpp_thread_poll_with_backoff(
3853 _Poll&& __poll, _Backoff&& __backoff, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero()) {
3954 auto const __start = chrono::high_resolution_clock::now();
4055 for (int __count = 0;;) {
4156 if (__poll())
42 return true; // __poll completion means success
57 return __poll_with_backoff_results::__poll_success;
4358 if (__count < __libcpp_polling_count) {
4459 __count += 1;
4560 continue;
4661 }
4762 chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start;
4863 if (__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed)
49 return false; // timeout failure
50 if (__backoff(__elapsed))
51 return false; // __backoff completion means failure
64 return __poll_with_backoff_results::__timeout;
65 if (auto __backoff_res = __backoff(__elapsed); __backoff_res == __backoff_results::__continue_poll)
66 continue;
67 else
68 return static_cast<__poll_with_backoff_results>(__backoff_res);
5269 }
5370}
5471
......@@ -59,7 +76,9 @@ _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_poll_with_b
5976// so this should most likely only be used on single-threaded systems where there
6077// are no other threads to compete with.
6178struct __spinning_backoff_policy {
62 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator()(chrono::nanoseconds const&) const { return false; }
79 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __backoff_results operator()(chrono::nanoseconds const&) const {
80 return __backoff_results::__continue_poll;
81 }
6382};
6483
6584_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__thread/support/c11.h+8-8
......@@ -39,17 +39,17 @@ inline _LIBCPP_HIDE_FROM_ABI int __libcpp_recursive_mutex_init(__libcpp_recursiv
3939 return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL;
4040}
4141
42inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
42_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI int
4343__libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t* __m) {
4444 return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
4545}
4646
47inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool
47_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI bool
4848__libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t* __m) {
4949 return mtx_trylock(__m) == thrd_success;
5050}
5151
52inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
52_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI int
5353__libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t* __m) {
5454 return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
5555}
......@@ -59,15 +59,15 @@ inline _LIBCPP_HIDE_FROM_ABI int __libcpp_recursive_mutex_destroy(__libcpp_recur
5959 return 0;
6060}
6161
62inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_lock(__libcpp_mutex_t* __m) {
62_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI int __libcpp_mutex_lock(__libcpp_mutex_t* __m) {
6363 return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
6464}
6565
66inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool __libcpp_mutex_trylock(__libcpp_mutex_t* __m) {
66_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_mutex_trylock(__libcpp_mutex_t* __m) {
6767 return mtx_trylock(__m) == thrd_success;
6868}
6969
70inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_unlock(__libcpp_mutex_t* __m) {
70_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI int __libcpp_mutex_unlock(__libcpp_mutex_t* __m) {
7171 return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
7272}
7373
......@@ -92,12 +92,12 @@ inline _LIBCPP_HIDE_FROM_ABI int __libcpp_condvar_broadcast(__libcpp_condvar_t*
9292 return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL;
9393}
9494
95inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
95_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI int
9696__libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m) {
9797 return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL;
9898}
9999
100inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
100_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI int
101101__libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts) {
102102 int __ec = cnd_timedwait(__cv, __m, __ts);
103103 return __ec == thrd_timedout ? ETIMEDOUT : __ec;
lib/libcxx/include/__thread/support/pthread.h+8-8
......@@ -72,17 +72,17 @@ inline _LIBCPP_HIDE_FROM_ABI int __libcpp_recursive_mutex_init(__libcpp_recursiv
7272 return 0;
7373}
7474
75inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
75_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI int
7676__libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t* __m) {
7777 return pthread_mutex_lock(__m);
7878}
7979
80inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool
80_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI bool
8181__libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t* __m) {
8282 return pthread_mutex_trylock(__m) == 0;
8383}
8484
85inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
85_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI int
8686__libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t* __m) {
8787 return pthread_mutex_unlock(__m);
8888}
......@@ -91,15 +91,15 @@ inline _LIBCPP_HIDE_FROM_ABI int __libcpp_recursive_mutex_destroy(__libcpp_recur
9191 return pthread_mutex_destroy(__m);
9292}
9393
94inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_lock(__libcpp_mutex_t* __m) {
94_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI int __libcpp_mutex_lock(__libcpp_mutex_t* __m) {
9595 return pthread_mutex_lock(__m);
9696}
9797
98inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool __libcpp_mutex_trylock(__libcpp_mutex_t* __m) {
98_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_mutex_trylock(__libcpp_mutex_t* __m) {
9999 return pthread_mutex_trylock(__m) == 0;
100100}
101101
102inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_unlock(__libcpp_mutex_t* __m) {
102_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI int __libcpp_mutex_unlock(__libcpp_mutex_t* __m) {
103103 return pthread_mutex_unlock(__m);
104104}
105105
......@@ -117,12 +117,12 @@ inline _LIBCPP_HIDE_FROM_ABI int __libcpp_condvar_broadcast(__libcpp_condvar_t*
117117 return pthread_cond_broadcast(__cv);
118118}
119119
120inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
120_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI int
121121__libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m) {
122122 return pthread_cond_wait(__cv, __m);
123123}
124124
125inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
125_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI int
126126__libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, __libcpp_timespec_t* __ts) {
127127 return pthread_cond_timedwait(__cv, __m, __ts);
128128}
lib/libcxx/include/__thread/support/windows.h+8-8
......@@ -36,22 +36,22 @@ typedef void* __libcpp_recursive_mutex_t[6];
3636
3737_LIBCPP_EXPORTED_FROM_ABI int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t* __m);
3838
39_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
39_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_EXPORTED_FROM_ABI int
4040__libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t* __m);
4141
42_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool
42_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_EXPORTED_FROM_ABI bool
4343__libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t* __m);
4444
45_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
45_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_EXPORTED_FROM_ABI int
4646__libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t* __m);
4747
4848_LIBCPP_EXPORTED_FROM_ABI int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t* __m);
4949
50_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_lock(__libcpp_mutex_t* __m);
50_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_EXPORTED_FROM_ABI int __libcpp_mutex_lock(__libcpp_mutex_t* __m);
5151
52_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool __libcpp_mutex_trylock(__libcpp_mutex_t* __m);
52_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_EXPORTED_FROM_ABI bool __libcpp_mutex_trylock(__libcpp_mutex_t* __m);
5353
54_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_unlock(__libcpp_mutex_t* __m);
54_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_EXPORTED_FROM_ABI int __libcpp_mutex_unlock(__libcpp_mutex_t* __m);
5555
5656_LIBCPP_EXPORTED_FROM_ABI int __libcpp_mutex_destroy(__libcpp_mutex_t* __m);
5757
......@@ -65,10 +65,10 @@ _LIBCPP_EXPORTED_FROM_ABI int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
6565
6666_LIBCPP_EXPORTED_FROM_ABI int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
6767
68_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
68_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_EXPORTED_FROM_ABI int
6969__libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
7070
71_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
71_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_EXPORTED_FROM_ABI int
7272__libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, __libcpp_timespec_t* __ts);
7373
7474_LIBCPP_EXPORTED_FROM_ABI int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
lib/libcxx/include/__thread/thread.h+13-8
......@@ -25,6 +25,8 @@
2525#include <__thread/support.h>
2626#include <__type_traits/decay.h>
2727#include <__type_traits/enable_if.h>
28#include <__type_traits/invoke.h>
29#include <__type_traits/is_constructible.h>
2830#include <__type_traits/is_same.h>
2931#include <__type_traits/remove_cvref.h>
3032#include <__utility/forward.h>
......@@ -155,8 +157,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) {
155157# ifndef _LIBCPP_CXX03_LANG
156158
157159template <class _TSp, class _Fp, class... _Args, size_t... _Indices>
158inline _LIBCPP_HIDE_FROM_ABI void __thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>) {
159 std::__invoke(std::move(std::get<1>(__t)), std::move(std::get<_Indices>(__t))...);
160inline _LIBCPP_HIDE_FROM_ABI void __thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __index_sequence<_Indices...>) {
161 std::__invoke(std::move(std::get<_Indices + 1>(__t))...);
160162}
161163
162164template <class _Fp>
......@@ -164,8 +166,7 @@ _LIBCPP_HIDE_FROM_ABI void* __thread_proxy(void* __vp) {
164166 // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...>
165167 unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
166168 __thread_local_data().set_pointer(std::get<0>(*__p.get()).release());
167 typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index;
168 std::__thread_execute(*__p.get(), _Index());
169 std::__thread_execute(*__p.get(), __make_index_sequence<tuple_size<_Fp>::value - 1>());
169170 return nullptr;
170171}
171172
......@@ -206,6 +207,10 @@ public:
206207# ifndef _LIBCPP_CXX03_LANG
207208 template <class _Fp, class... _Args, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value, int> = 0>
208209 _LIBCPP_HIDE_FROM_ABI explicit thread(_Fp&& __f, _Args&&... __args) {
210 static_assert(is_constructible<__decay_t<_Fp>, _Fp>::value, "");
211 static_assert(_And<is_constructible<__decay_t<_Args>, _Args>...>::value, "");
212 static_assert(__is_invocable_v<__decay_t<_Fp>, __decay_t<_Args>...>, "");
213
209214 typedef unique_ptr<__thread_struct> _TSPtr;
210215 _TSPtr __tsp(new __thread_struct);
211216 typedef tuple<_TSPtr, __decay_t<_Fp>, __decay_t<_Args>...> _Gp;
......@@ -243,13 +248,13 @@ public:
243248
244249 _LIBCPP_HIDE_FROM_ABI void swap(thread& __t) _NOEXCEPT { std::swap(__t_, __t.__t_); }
245250
246 _LIBCPP_HIDE_FROM_ABI bool joinable() const _NOEXCEPT { return !__libcpp_thread_isnull(&__t_); }
251 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool joinable() const _NOEXCEPT { return !__libcpp_thread_isnull(&__t_); }
247252 void join();
248253 void detach();
249 _LIBCPP_HIDE_FROM_ABI id get_id() const _NOEXCEPT { return __libcpp_thread_get_id(&__t_); }
250 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() _NOEXCEPT { return __t_; }
254 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI id get_id() const _NOEXCEPT { return __libcpp_thread_get_id(&__t_); }
255 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() _NOEXCEPT { return __t_; }
251256
252 static unsigned hardware_concurrency() _NOEXCEPT;
257 [[__nodiscard__]] static unsigned hardware_concurrency() _NOEXCEPT;
253258};
254259
255260inline _LIBCPP_HIDE_FROM_ABI void swap(thread& __x, thread& __y) _NOEXCEPT { __x.swap(__y); }
lib/libcxx/include/__thread/timed_backoff_policy.h+3-2
......@@ -11,6 +11,7 @@
1111#define _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H
1212
1313#include <__config>
14#include <__thread/poll_with_backoff.h>
1415
1516#if _LIBCPP_HAS_THREADS
1617
......@@ -24,7 +25,7 @@
2425_LIBCPP_BEGIN_NAMESPACE_STD
2526
2627struct __libcpp_timed_backoff_policy {
27 _LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const {
28 _LIBCPP_HIDE_FROM_ABI __backoff_results operator()(chrono::nanoseconds __elapsed) const {
2829 if (__elapsed > chrono::milliseconds(128))
2930 __libcpp_thread_sleep_for(chrono::milliseconds(8));
3031 else if (__elapsed > chrono::microseconds(64))
......@@ -33,7 +34,7 @@ struct __libcpp_timed_backoff_policy {
3334 __libcpp_thread_yield();
3435 else {
3536 } // poll
36 return false;
37 return __backoff_results::__continue_poll;
3738 }
3839};
3940
lib/libcxx/include/__tree+849-701
......@@ -11,37 +11,39 @@
1111#define _LIBCPP___TREE
1212
1313#include <__algorithm/min.h>
14#include <__algorithm/specialized_algorithms.h>
1415#include <__assert>
1516#include <__config>
16#include <__fwd/map.h>
1717#include <__fwd/pair.h>
18#include <__fwd/set.h>
1918#include <__iterator/distance.h>
2019#include <__iterator/iterator_traits.h>
2120#include <__iterator/next.h>
2221#include <__memory/addressof.h>
2322#include <__memory/allocator_traits.h>
2423#include <__memory/compressed_pair.h>
24#include <__memory/construct_at.h>
2525#include <__memory/pointer_traits.h>
2626#include <__memory/swap_allocator.h>
2727#include <__memory/unique_ptr.h>
28#include <__type_traits/can_extract_key.h>
28#include <__new/launder.h>
2929#include <__type_traits/copy_cvref.h>
3030#include <__type_traits/enable_if.h>
3131#include <__type_traits/invoke.h>
32#include <__type_traits/is_const.h>
3332#include <__type_traits/is_constructible.h>
3433#include <__type_traits/is_nothrow_assignable.h>
3534#include <__type_traits/is_nothrow_constructible.h>
3635#include <__type_traits/is_same.h>
36#include <__type_traits/is_specialization.h>
3737#include <__type_traits/is_swappable.h>
38#include <__type_traits/make_transparent.h>
3839#include <__type_traits/remove_const.h>
39#include <__type_traits/remove_const_ref.h>
4040#include <__type_traits/remove_cvref.h>
4141#include <__utility/forward.h>
42#include <__utility/lazy_synth_three_way_comparator.h>
4243#include <__utility/move.h>
4344#include <__utility/pair.h>
4445#include <__utility/swap.h>
46#include <__utility/try_key_extraction.h>
4547#include <limits>
4648
4749#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
......@@ -51,14 +53,31 @@
5153_LIBCPP_PUSH_MACROS
5254#include <__undef_macros>
5355
54_LIBCPP_BEGIN_NAMESPACE_STD
56_LIBCPP_DIAGNOSTIC_PUSH
57// GCC complains about the backslashes at the end, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121528
58_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wcomment")
59// __tree is a red-black-tree implementation used for the associative containers (i.e. (multi)map/set). It stores
60// - (1) a pointer to the node with the smallest (i.e. leftmost) element, namely __begin_node_
61// - (2) the number of nodes in the tree, namely __size_
62// - (3) a pointer to the root of the tree, namely __end_node_
63//
64// Storing (1) and (2) is required to allow for constant time lookups. A tree looks like this in memory:
65//
66// __end_node_
67// |
68// root
69// / \
70// l1 r1
71// / \ / \
72// ... ... ... ...
73//
74// All nodes except __end_node_ have a __left_ and __right_ pointer as well as a __parent_ pointer.
75// __end_node_ only contains a __left_ pointer, which points to the root of the tree.
76// This layout allows for iteration through the tree without a need for special handling of the end node. See
77// __tree_next_iter and __tree_prev_iter for more details.
78_LIBCPP_DIAGNOSTIC_POP
5579
56template <class _Tp, class _Compare, class _Allocator>
57class __tree;
58template <class _Tp, class _NodePtr, class _DiffType>
59class __tree_iterator;
60template <class _Tp, class _ConstNodePtr, class _DiffType>
61class __tree_const_iterator;
80_LIBCPP_BEGIN_NAMESPACE_STD
6281
6382template <class _Pointer>
6483class __tree_end_node;
......@@ -70,13 +89,6 @@ class __tree_node;
7089template <class _Key, class _Value>
7190struct __value_type;
7291
73template <class _Allocator>
74class __map_node_destructor;
75template <class _TreeIterator>
76class __map_iterator;
77template <class _TreeIterator>
78class __map_const_iterator;
79
8092/*
8193
8294_NodePtr algorithms
......@@ -185,6 +197,11 @@ _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_next(_NodePtr __x) _NOEXCEPT {
185197 return __x->__parent_unsafe();
186198}
187199
200// __tree_next_iter and __tree_prev_iter implement iteration through the tree. The order is as follows:
201// left sub-tree -> node -> right sub-tree. When the right-most node of a sub-tree is reached, we walk up the tree until
202// we find a node where we were in the left sub-tree. We are _always_ in a left sub-tree, since the __end_node_ points
203// to the actual root of the tree through a __left_ pointer. Incrementing the end() pointer is UB, so we can assume that
204// never happens.
188205template <class _EndNodePtr, class _NodePtr>
189206inline _LIBCPP_HIDE_FROM_ABI _EndNodePtr __tree_next_iter(_NodePtr __x) _NOEXCEPT {
190207 _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
......@@ -494,16 +511,7 @@ _LIBCPP_HIDE_FROM_ABI void __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEP
494511// node traits
495512
496513template <class _Tp>
497struct __is_tree_value_type_imp : false_type {};
498
499template <class _Key, class _Value>
500struct __is_tree_value_type_imp<__value_type<_Key, _Value> > : true_type {};
501
502template <class... _Args>
503struct __is_tree_value_type : false_type {};
504
505template <class _One>
506struct __is_tree_value_type<_One> : __is_tree_value_type_imp<__remove_cvref_t<_One> > {};
514inline const bool __is_tree_value_type_v = __is_specialization_v<_Tp, __value_type>;
507515
508516template <class _Tp>
509517struct __get_tree_key_type {
......@@ -549,15 +557,14 @@ private:
549557template <class _Pointer>
550558class __tree_end_node {
551559public:
552 typedef _Pointer pointer;
560 using pointer = _Pointer;
553561 pointer __left_;
554562
555563 _LIBCPP_HIDE_FROM_ABI __tree_end_node() _NOEXCEPT : __left_() {}
556564};
557565
558566template <class _VoidPtr>
559class _LIBCPP_STANDALONE_DEBUG
560__tree_node_base : public __tree_end_node<__rebind_pointer_t<_VoidPtr, __tree_node_base<_VoidPtr> > > {
567class __tree_node_base : public __tree_end_node<__rebind_pointer_t<_VoidPtr, __tree_node_base<_VoidPtr> > > {
561568public:
562569 using pointer = __rebind_pointer_t<_VoidPtr, __tree_node_base>;
563570 using __end_node_pointer _LIBCPP_NODEBUG = __rebind_pointer_t<_VoidPtr, __tree_end_node<pointer> >;
......@@ -570,20 +577,41 @@ public:
570577
571578 _LIBCPP_HIDE_FROM_ABI void __set_parent(pointer __p) { __parent_ = static_cast<__end_node_pointer>(__p); }
572579
573 ~__tree_node_base() = delete;
580 _LIBCPP_HIDE_FROM_ABI __tree_node_base() = default;
574581 __tree_node_base(__tree_node_base const&) = delete;
575582 __tree_node_base& operator=(__tree_node_base const&) = delete;
576583};
577584
578585template <class _Tp, class _VoidPtr>
579class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> {
586class __tree_node : public __tree_node_base<_VoidPtr> {
580587public:
581588 using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t<_Tp>;
582589
583 __node_value_type __value_;
590// We use a union to avoid initialization during member initialization, which allows us
591// to use the allocator from the container to construct the `__node_value_type` in the
592// memory provided by the union member
593#ifndef _LIBCPP_CXX03_LANG
594
595private:
596 union {
597 __node_value_type __value_;
598 };
584599
600public:
585601 _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return __value_; }
602#else
603
604private:
605 _ALIGNAS_TYPE(__node_value_type) unsigned char __buffer_[sizeof(__node_value_type)];
606
607public:
608 _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return *reinterpret_cast<__node_value_type*>(__buffer_); }
609#endif
586610
611 template <class _Alloc, class... _Args>
612 _LIBCPP_HIDE_FROM_ABI explicit __tree_node(_Alloc& __na, _Args&&... __args) {
613 allocator_traits<_Alloc>::construct(__na, std::addressof(__get_value()), std::forward<_Args>(__args)...);
614 }
587615 ~__tree_node() = delete;
588616 __tree_node(__tree_node const&) = delete;
589617 __tree_node& operator=(__tree_node const&) = delete;
......@@ -591,11 +619,11 @@ public:
591619
592620template <class _Allocator>
593621class __tree_node_destructor {
594 typedef _Allocator allocator_type;
595 typedef allocator_traits<allocator_type> __alloc_traits;
622 using allocator_type = _Allocator;
623 using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;
596624
597625public:
598 typedef typename __alloc_traits::pointer pointer;
626 using pointer = typename __alloc_traits::pointer;
599627
600628private:
601629 allocator_type& __na_;
......@@ -612,7 +640,7 @@ public:
612640
613641 _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
614642 if (__value_constructed)
615 __alloc_traits::destroy(__na_, std::addressof(__p->__value_));
643 __alloc_traits::destroy(__na_, std::addressof(__p->__get_value()));
616644 if (__p)
617645 __alloc_traits::deallocate(__na_, __p, 1);
618646 }
......@@ -630,12 +658,60 @@ struct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc> :
630658};
631659#endif
632660
661// Do an in-order traversal of the tree until `__break` returns true. Takes the root node of the tree.
662template <class _Reference, class _Break, class _NodePtr, class _Func, class _Proj>
663#ifndef _LIBCPP_COMPILER_GCC // This function is recursive, so GCC complains about always_inline.
664_LIBCPP_HIDE_FROM_ABI
665#endif
666bool __tree_iterate_from_root(_Break __break, _NodePtr __root, _Func& __func, _Proj& __proj) {
667 if (__root->__left_) {
668 if (std::__tree_iterate_from_root<_Reference>(__break, static_cast<_NodePtr>(__root->__left_), __func, __proj))
669 return true;
670 }
671 if (__break(__root))
672 return true;
673 std::__invoke(__func, std::__invoke(__proj, static_cast<_Reference>(__root->__get_value())));
674 if (__root->__right_)
675 return std::__tree_iterate_from_root<_Reference>(__break, static_cast<_NodePtr>(__root->__right_), __func, __proj);
676 return false;
677}
678
679// Do an in-order traversal of the tree from __first to __last.
680template <class _NodeIter, class _Func, class _Proj>
681_LIBCPP_HIDE_FROM_ABI void
682__tree_iterate_subrange(_NodeIter __first_it, _NodeIter __last_it, _Func& __func, _Proj& __proj) {
683 using _NodePtr = typename _NodeIter::__node_pointer;
684 using _Reference = typename _NodeIter::reference;
685
686 auto __first = __first_it.__ptr_;
687 auto __last = __last_it.__ptr_;
688
689 while (true) {
690 if (__first == __last)
691 return;
692 const auto __nfirst = static_cast<_NodePtr>(__first);
693 std::__invoke(__func, std::__invoke(__proj, static_cast<_Reference>(__nfirst->__get_value())));
694 if (__nfirst->__right_) {
695 if (std::__tree_iterate_from_root<_Reference>(
696 [&](_NodePtr __node) -> bool { return __node == __last; },
697 static_cast<_NodePtr>(__nfirst->__right_),
698 __func,
699 __proj))
700 return;
701 }
702 while (!std::__tree_is_left_child(static_cast<_NodePtr>(__first)))
703 __first = static_cast<_NodePtr>(__first)->__parent_;
704 __first = static_cast<_NodePtr>(__first)->__parent_;
705 }
706}
707
633708template <class _Tp, class _NodePtr, class _DiffType>
634709class __tree_iterator {
635 typedef __tree_node_types<_NodePtr> _NodeTypes;
636 typedef _NodePtr __node_pointer;
637 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
638 typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
710 using _NodeTypes _LIBCPP_NODEBUG = __tree_node_types<_NodePtr>;
711 // NOLINTNEXTLINE(libcpp-nodebug-on-aliases) lldb relies on this alias for pretty printing
712 using __node_pointer = _NodePtr;
713 using __node_base_pointer _LIBCPP_NODEBUG = typename _NodeTypes::__node_base_pointer;
714 using __end_node_pointer _LIBCPP_NODEBUG = typename _NodeTypes::__end_node_pointer;
639715
640716 __end_node_pointer __ptr_;
641717
......@@ -646,15 +722,12 @@ public:
646722 using reference = value_type&;
647723 using pointer = __rebind_pointer_t<_NodePtr, value_type>;
648724
649 _LIBCPP_HIDE_FROM_ABI __tree_iterator() _NOEXCEPT
650#if _LIBCPP_STD_VER >= 14
651 : __ptr_(nullptr)
652#endif
653 {
654 }
725 _LIBCPP_HIDE_FROM_ABI __tree_iterator() _NOEXCEPT : __ptr_(nullptr) {}
655726
656 _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__value_; }
657 _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__get_np()->__value_); }
727 _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__get_value(); }
728 _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
729 return pointer_traits<pointer>::pointer_to(__get_np()->__get_value());
730 }
658731
659732 _LIBCPP_HIDE_FROM_ABI __tree_iterator& operator++() {
660733 __ptr_ = std::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_));
......@@ -691,50 +764,54 @@ private:
691764 friend class __tree;
692765 template <class, class, class>
693766 friend class __tree_const_iterator;
694 template <class>
695 friend class __map_iterator;
696 template <class, class, class, class>
697 friend class map;
698 template <class, class, class, class>
699 friend class multimap;
700 template <class, class, class>
701 friend class set;
702 template <class, class, class>
703 friend class multiset;
767
768 template <class _NodeIter, class _Func, class _Proj>
769 friend void __tree_iterate_subrange(_NodeIter, _NodeIter, _Func&, _Proj&);
770};
771
772#ifndef _LIBCPP_CXX03_LANG
773// This also handles {multi,}set::iterator, since they're just aliases to __tree::iterator
774template <class _Tp, class _NodePtr, class _DiffType>
775struct __specialized_algorithm<
776 _Algorithm::__for_each,
777 __iterator_pair<__tree_iterator<_Tp, _NodePtr, _DiffType>, __tree_iterator<_Tp, _NodePtr, _DiffType>>> {
778 static const bool __has_algorithm = true;
779
780 using __iterator _LIBCPP_NODEBUG = __tree_iterator<_Tp, _NodePtr, _DiffType>;
781
782 template <class _Func, class _Proj>
783 _LIBCPP_HIDE_FROM_ABI static void operator()(__iterator __first, __iterator __last, _Func& __func, _Proj& __proj) {
784 std::__tree_iterate_subrange(__first, __last, __func, __proj);
785 }
704786};
787#endif
705788
706789template <class _Tp, class _NodePtr, class _DiffType>
707790class __tree_const_iterator {
708 typedef __tree_node_types<_NodePtr> _NodeTypes;
791 using _NodeTypes _LIBCPP_NODEBUG = __tree_node_types<_NodePtr>;
709792 // NOLINTNEXTLINE(libcpp-nodebug-on-aliases) lldb relies on this alias for pretty printing
710 using __node_pointer = _NodePtr;
711 typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
712 typedef typename _NodeTypes::__end_node_pointer __end_node_pointer;
793 using __node_pointer = _NodePtr;
794 using __node_base_pointer _LIBCPP_NODEBUG = typename _NodeTypes::__node_base_pointer;
795 using __end_node_pointer _LIBCPP_NODEBUG = typename _NodeTypes::__end_node_pointer;
713796
714797 __end_node_pointer __ptr_;
715798
716799public:
717 using iterator_category = bidirectional_iterator_tag;
718 using value_type = __get_node_value_type_t<_Tp>;
719 using difference_type = _DiffType;
720 using reference = const value_type&;
721 using pointer = __rebind_pointer_t<_NodePtr, const value_type>;
800 using iterator_category = bidirectional_iterator_tag;
801 using value_type = __get_node_value_type_t<_Tp>;
802 using difference_type = _DiffType;
803 using reference = const value_type&;
804 using pointer = __rebind_pointer_t<_NodePtr, const value_type>;
805 using __non_const_iterator _LIBCPP_NODEBUG = __tree_iterator<_Tp, __node_pointer, difference_type>;
722806
723 _LIBCPP_HIDE_FROM_ABI __tree_const_iterator() _NOEXCEPT
724#if _LIBCPP_STD_VER >= 14
725 : __ptr_(nullptr)
726#endif
727 {
728 }
729
730private:
731 typedef __tree_iterator<_Tp, __node_pointer, difference_type> __non_const_iterator;
807 _LIBCPP_HIDE_FROM_ABI __tree_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
732808
733public:
734809 _LIBCPP_HIDE_FROM_ABI __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
735810
736 _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__value_; }
737 _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__get_np()->__value_); }
811 _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__get_value(); }
812 _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
813 return pointer_traits<pointer>::pointer_to(__get_np()->__get_value());
814 }
738815
739816 _LIBCPP_HIDE_FROM_ABI __tree_const_iterator& operator++() {
740817 __ptr_ = std::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_));
......@@ -772,18 +849,28 @@ private:
772849
773850 template <class, class, class>
774851 friend class __tree;
775 template <class, class, class, class>
776 friend class map;
777 template <class, class, class, class>
778 friend class multimap;
779 template <class, class, class>
780 friend class set;
781 template <class, class, class>
782 friend class multiset;
783 template <class>
784 friend class __map_const_iterator;
852
853 template <class _NodeIter, class _Func, class _Proj>
854 friend void __tree_iterate_subrange(_NodeIter, _NodeIter, _Func&, _Proj&);
785855};
786856
857#ifndef _LIBCPP_CXX03_LANG
858// This also handles {multi,}set::const_iterator, since they're just aliases to __tree::iterator
859template <class _Tp, class _NodePtr, class _DiffType>
860struct __specialized_algorithm<
861 _Algorithm::__for_each,
862 __iterator_pair<__tree_const_iterator<_Tp, _NodePtr, _DiffType>, __tree_const_iterator<_Tp, _NodePtr, _DiffType>>> {
863 static const bool __has_algorithm = true;
864
865 using __iterator _LIBCPP_NODEBUG = __tree_const_iterator<_Tp, _NodePtr, _DiffType>;
866
867 template <class _Func, class _Proj>
868 _LIBCPP_HIDE_FROM_ABI static void operator()(__iterator __first, __iterator __last, _Func& __func, _Proj& __proj) {
869 std::__tree_iterate_subrange(__first, __last, __func, __proj);
870 }
871};
872#endif
873
787874template <class _Tp, class _Compare>
788875#ifndef _LIBCPP_CXX03_LANG
789876_LIBCPP_DIAGNOSE_WARNING(!__is_invocable_v<_Compare const&, _Tp const&, _Tp const&>,
......@@ -794,21 +881,20 @@ int __diagnose_non_const_comparator();
794881template <class _Tp, class _Compare, class _Allocator>
795882class __tree {
796883public:
797 using value_type = __get_node_value_type_t<_Tp>;
798 typedef _Compare value_compare;
799 typedef _Allocator allocator_type;
884 using value_type = __get_node_value_type_t<_Tp>;
885 using value_compare = _Compare;
886 using allocator_type = _Allocator;
800887
801888private:
802 typedef allocator_traits<allocator_type> __alloc_traits;
803 using key_type = __get_tree_key_type_t<_Tp>;
889 using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>;
890 using key_type = __get_tree_key_type_t<_Tp>;
804891
805892public:
806 typedef typename __alloc_traits::pointer pointer;
807 typedef typename __alloc_traits::const_pointer const_pointer;
808 typedef typename __alloc_traits::size_type size_type;
809 typedef typename __alloc_traits::difference_type difference_type;
893 using pointer = typename __alloc_traits::pointer;
894 using const_pointer = typename __alloc_traits::const_pointer;
895 using size_type = typename __alloc_traits::size_type;
896 using difference_type = typename __alloc_traits::difference_type;
810897
811public:
812898 using __void_pointer _LIBCPP_NODEBUG = typename __alloc_traits::void_pointer;
813899
814900 using __node _LIBCPP_NODEBUG = __tree_node<_Tp, __void_pointer>;
......@@ -821,22 +907,8 @@ public:
821907 using __end_node_t _LIBCPP_NODEBUG = __tree_end_node<__node_base_pointer>;
822908 using __end_node_pointer _LIBCPP_NODEBUG = __rebind_pointer_t<__void_pointer, __end_node_t>;
823909
824 using __parent_pointer _LIBCPP_NODEBUG = __end_node_pointer; // TODO: Remove this once the uses in <map> are removed
825
826 typedef __rebind_alloc<__alloc_traits, __node> __node_allocator;
827 typedef allocator_traits<__node_allocator> __node_traits;
828
829// TODO(LLVM 22): Remove this check
830#ifndef _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB
831 static_assert(sizeof(__node_base_pointer) == sizeof(__end_node_pointer) && _LIBCPP_ALIGNOF(__node_base_pointer) ==
832 _LIBCPP_ALIGNOF(__end_node_pointer),
833 "It looks like you are using std::__tree (an implementation detail for (multi)map/set) with a fancy "
834 "pointer type that thas a different representation depending on whether it points to a __tree base "
835 "pointer or a __tree node pointer (both of which are implementation details of the standard library). "
836 "This means that your ABI is being broken between LLVM 19 and LLVM 20. If you don't care about your "
837 "ABI being broken, define the _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB macro to silence this "
838 "diagnostic.");
839#endif
910 using __node_allocator _LIBCPP_NODEBUG = __rebind_alloc<__alloc_traits, __node>;
911 using __node_traits _LIBCPP_NODEBUG = allocator_traits<__node_allocator>;
840912
841913private:
842914 // check for sane allocator pointer rebinding semantics. Rebinding the
......@@ -844,8 +916,8 @@ private:
844916 // the pointer using 'pointer_traits'.
845917 static_assert(is_same<__node_pointer, typename __node_traits::pointer>::value,
846918 "Allocator does not rebind pointers in a sane manner.");
847 typedef __rebind_alloc<__node_traits, __node_base> __node_base_allocator;
848 typedef allocator_traits<__node_base_allocator> __node_base_traits;
919 using __node_base_allocator _LIBCPP_NODEBUG = __rebind_alloc<__node_traits, __node_base>;
920 using __node_base_traits _LIBCPP_NODEBUG = allocator_traits<__node_base_allocator>;
849921 static_assert(is_same<__node_base_pointer, typename __node_base_traits::pointer>::value,
850922 "Allocator does not rebind pointers in a sane manner.");
851923
......@@ -865,17 +937,11 @@ public:
865937
866938private:
867939 _LIBCPP_HIDE_FROM_ABI const __node_allocator& __node_alloc() const _NOEXCEPT { return __node_alloc_; }
868 _LIBCPP_HIDE_FROM_ABI __end_node_pointer& __begin_node() _NOEXCEPT { return __begin_node_; }
869 _LIBCPP_HIDE_FROM_ABI const __end_node_pointer& __begin_node() const _NOEXCEPT { return __begin_node_; }
870940
871941public:
872942 _LIBCPP_HIDE_FROM_ABI allocator_type __alloc() const _NOEXCEPT { return allocator_type(__node_alloc()); }
873943
874private:
875 _LIBCPP_HIDE_FROM_ABI size_type& size() _NOEXCEPT { return __size_; }
876
877public:
878 _LIBCPP_HIDE_FROM_ABI const size_type& size() const _NOEXCEPT { return __size_; }
944 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }
879945 _LIBCPP_HIDE_FROM_ABI value_compare& value_comp() _NOEXCEPT { return __value_comp_; }
880946 _LIBCPP_HIDE_FROM_ABI const value_compare& value_comp() const _NOEXCEPT { return __value_comp_; }
881947
......@@ -888,32 +954,61 @@ public:
888954 return std::addressof(__end_node()->__left_);
889955 }
890956
891 typedef __tree_iterator<_Tp, __node_pointer, difference_type> iterator;
892 typedef __tree_const_iterator<_Tp, __node_pointer, difference_type> const_iterator;
957 using iterator = __tree_iterator<_Tp, __node_pointer, difference_type>;
958 using const_iterator = __tree_const_iterator<_Tp, __node_pointer, difference_type>;
893959
894960 _LIBCPP_HIDE_FROM_ABI explicit __tree(const value_compare& __comp) _NOEXCEPT_(
895 is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_copy_constructible<value_compare>::value);
896 _LIBCPP_HIDE_FROM_ABI explicit __tree(const allocator_type& __a);
897 _LIBCPP_HIDE_FROM_ABI __tree(const value_compare& __comp, const allocator_type& __a);
961 is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_copy_constructible<value_compare>::value)
962 : __size_(0), __value_comp_(__comp) {
963 __begin_node_ = __end_node();
964 }
965
966 _LIBCPP_HIDE_FROM_ABI explicit __tree(const allocator_type& __a)
967 : __begin_node_(), __node_alloc_(__node_allocator(__a)), __size_(0) {
968 __begin_node_ = __end_node();
969 }
970
971 _LIBCPP_HIDE_FROM_ABI __tree(const value_compare& __comp, const allocator_type& __a)
972 : __begin_node_(), __node_alloc_(__node_allocator(__a)), __size_(0), __value_comp_(__comp) {
973 __begin_node_ = __end_node();
974 }
975
898976 _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __t);
977
978 _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __other, const allocator_type& __alloc)
979 : __begin_node_(__end_node()), __node_alloc_(__alloc), __size_(0), __value_comp_(__other.value_comp()) {
980 if (__other.size() == 0)
981 return;
982
983 *__root_ptr() = static_cast<__node_base_pointer>(__copy_construct_tree(__other.__root()));
984 __root()->__parent_ = __end_node();
985 __begin_node_ = static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_));
986 __size_ = __other.size();
987 }
988
899989 _LIBCPP_HIDE_FROM_ABI __tree& operator=(const __tree& __t);
900990 template <class _ForwardIterator>
901991 _LIBCPP_HIDE_FROM_ABI void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
902 template <class _InputIterator>
903 _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last);
904992 _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t) _NOEXCEPT_(
905993 is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value);
906994 _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t, const allocator_type& __a);
995
907996 _LIBCPP_HIDE_FROM_ABI __tree& operator=(__tree&& __t)
908997 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
909998 ((__node_traits::propagate_on_container_move_assignment::value &&
910999 is_nothrow_move_assignable<__node_allocator>::value) ||
911 allocator_traits<__node_allocator>::is_always_equal::value));
1000 allocator_traits<__node_allocator>::is_always_equal::value)) {
1001 __move_assign(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
1002 return *this;
1003 }
9121004
913 _LIBCPP_HIDE_FROM_ABI ~__tree();
1005 _LIBCPP_HIDE_FROM_ABI ~__tree() {
1006 static_assert(is_copy_constructible<value_compare>::value, "Comparator must be copy-constructible.");
1007 destroy(__root());
1008 }
9141009
915 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__begin_node()); }
916 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return const_iterator(__begin_node()); }
1010 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__begin_node_); }
1011 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return const_iterator(__begin_node_); }
9171012 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(__end_node()); }
9181013 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return const_iterator(__end_node()); }
9191014
......@@ -931,116 +1026,151 @@ public:
9311026 _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>);
9321027#endif
9331028
934 template <class _Key, class... _Args>
935 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args&&... __args);
936 template <class _Key, class... _Args>
937 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...);
938
939 template <class... _Args>
940 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
941
942 template <class... _Args>
943 _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
944
9451029 template <class... _Args>
9461030 _LIBCPP_HIDE_FROM_ABI iterator __emplace_multi(_Args&&... __args);
9471031
9481032 template <class... _Args>
9491033 _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
9501034
951 template <class _Pp>
952 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_Pp&& __x) {
953 return __emplace_unique_extract_key(std::forward<_Pp>(__x), __can_extract_key<_Pp, key_type>());
954 }
955
956 template <class _First,
957 class _Second,
958 __enable_if_t<__can_extract_map_key<_First, key_type, value_type>::value, int> = 0>
959 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_First&& __f, _Second&& __s) {
960 return __emplace_unique_key_args(__f, std::forward<_First>(__f), std::forward<_Second>(__s));
961 }
962
9631035 template <class... _Args>
9641036 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_Args&&... __args) {
965 return __emplace_unique_impl(std::forward<_Args>(__args)...);
966 }
967
968 template <class _Pp>
969 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
970 return __emplace_unique_impl(std::forward<_Pp>(__x));
971 }
972
973 template <class _Pp>
974 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
975 return __emplace_unique_key_args(__x, std::forward<_Pp>(__x));
976 }
977
978 template <class _Pp>
979 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
980 return __emplace_unique_key_args(__x.first, std::forward<_Pp>(__x));
981 }
982
983 template <class _Pp>
984 _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) {
985 return __emplace_hint_unique_extract_key(__p, std::forward<_Pp>(__x), __can_extract_key<_Pp, key_type>());
986 }
987
988 template <class _First,
989 class _Second,
990 __enable_if_t<__can_extract_map_key<_First, key_type, value_type>::value, int> = 0>
991 _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) {
992 return __emplace_hint_unique_key_args(__p, __f, std::forward<_First>(__f), std::forward<_Second>(__s)).first;
1037 return std::__try_key_extraction<key_type>(
1038 [this](const key_type& __key, _Args&&... __args2) {
1039 auto [__parent, __child] = __find_equal(__key);
1040 __node_pointer __r = static_cast<__node_pointer>(__child);
1041 bool __inserted = false;
1042 if (__child == nullptr) {
1043 __node_holder __h = __construct_node(std::forward<_Args>(__args2)...);
1044 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1045 __r = __h.release();
1046 __inserted = true;
1047 }
1048 return pair<iterator, bool>(iterator(__r), __inserted);
1049 },
1050 [this](_Args&&... __args2) {
1051 __node_holder __h = __construct_node(std::forward<_Args>(__args2)...);
1052 auto [__parent, __child] = __find_equal(__h->__get_value());
1053 __node_pointer __r = static_cast<__node_pointer>(__child);
1054 bool __inserted = false;
1055 if (__child == nullptr) {
1056 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1057 __r = __h.release();
1058 __inserted = true;
1059 }
1060 return pair<iterator, bool>(iterator(__r), __inserted);
1061 },
1062 std::forward<_Args>(__args)...);
9931063 }
9941064
9951065 template <class... _Args>
996 _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
997 return __emplace_hint_unique_impl(__p, std::forward<_Args>(__args)...);
1066 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
1067 return std::__try_key_extraction<key_type>(
1068 [this, __p](const key_type& __key, _Args&&... __args2) {
1069 __node_base_pointer __dummy;
1070 auto [__parent, __child] = __find_equal(__p, __dummy, __key);
1071 __node_pointer __r = static_cast<__node_pointer>(__child);
1072 bool __inserted = false;
1073 if (__child == nullptr) {
1074 __node_holder __h = __construct_node(std::forward<_Args>(__args2)...);
1075 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1076 __r = __h.release();
1077 __inserted = true;
1078 }
1079 return pair<iterator, bool>(iterator(__r), __inserted);
1080 },
1081 [this, __p](_Args&&... __args2) {
1082 __node_holder __h = __construct_node(std::forward<_Args>(__args2)...);
1083 __node_base_pointer __dummy;
1084 auto [__parent, __child] = __find_equal(__p, __dummy, __h->__get_value());
1085 __node_pointer __r = static_cast<__node_pointer>(__child);
1086 if (__child == nullptr) {
1087 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1088 __r = __h.release();
1089 }
1090 return pair<iterator, bool>(iterator(__r), __child == nullptr);
1091 },
1092 std::forward<_Args>(__args)...);
9981093 }
9991094
1000 template <class _Pp>
1001 _LIBCPP_HIDE_FROM_ABI iterator
1002 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) {
1003 return __emplace_hint_unique_impl(__p, std::forward<_Pp>(__x));
1004 }
1095 template <class _InIter, class _Sent>
1096 _LIBCPP_HIDE_FROM_ABI void __insert_range_multi(_InIter __first, _Sent __last) {
1097 if (__first == __last)
1098 return;
10051099
1006 template <class _Pp>
1007 _LIBCPP_HIDE_FROM_ABI iterator
1008 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) {
1009 return __emplace_hint_unique_key_args(__p, __x, std::forward<_Pp>(__x)).first;
1010 }
1100 if (__root() == nullptr) { // Make sure we always have a root node
1101 __insert_node_at(
1102 __end_node(), __end_node()->__left_, static_cast<__node_base_pointer>(__construct_node(*__first).release()));
1103 ++__first;
1104 }
10111105
1012 template <class _Pp>
1013 _LIBCPP_HIDE_FROM_ABI iterator
1014 __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) {
1015 return __emplace_hint_unique_key_args(__p, __x.first, std::forward<_Pp>(__x)).first;
1016 }
1106 auto __max_node = static_cast<__node_pointer>(std::__tree_max(static_cast<__node_base_pointer>(__root())));
10171107
1018 template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type<_ValueT>::value, int> = 0>
1019 _LIBCPP_HIDE_FROM_ABI void
1020 __insert_unique_from_orphaned_node(const_iterator __p, __get_node_value_type_t<_Tp>&& __value) {
1021 __emplace_hint_unique(__p, const_cast<key_type&&>(__value.first), std::move(__value.second));
1108 for (; __first != __last; ++__first) {
1109 __node_holder __nd = __construct_node(*__first);
1110 // Always check the max node first. This optimizes for sorted ranges inserted at the end.
1111 if (!value_comp()(__nd->__get_value(), __max_node->__get_value())) { // __node >= __max_val
1112 __insert_node_at(static_cast<__end_node_pointer>(__max_node),
1113 __max_node->__right_,
1114 static_cast<__node_base_pointer>(__nd.get()));
1115 __max_node = __nd.release();
1116 } else {
1117 __end_node_pointer __parent;
1118 __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__get_value());
1119 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd.release()));
1120 }
1121 }
10221122 }
10231123
1024 template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type<_ValueT>::value, int> = 0>
1025 _LIBCPP_HIDE_FROM_ABI void __insert_unique_from_orphaned_node(const_iterator __p, _Tp&& __value) {
1026 __emplace_hint_unique(__p, std::move(__value));
1027 }
1124 template <class _InIter, class _Sent>
1125 _LIBCPP_HIDE_FROM_ABI void __insert_range_unique(_InIter __first, _Sent __last) {
1126 if (__first == __last)
1127 return;
10281128
1029 template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type<_ValueT>::value, int> = 0>
1030 _LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(const_iterator __p, value_type&& __value) {
1031 __emplace_hint_multi(__p, const_cast<key_type&&>(__value.first), std::move(__value.second));
1032 }
1129 if (__root() == nullptr) {
1130 __insert_node_at(
1131 __end_node(), __end_node()->__left_, static_cast<__node_base_pointer>(__construct_node(*__first).release()));
1132 ++__first;
1133 }
10331134
1034 template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type<_ValueT>::value, int> = 0>
1035 _LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(const_iterator __p, _Tp&& __value) {
1036 __emplace_hint_multi(__p, std::move(__value));
1135 auto __max_node = static_cast<__node_pointer>(std::__tree_max(static_cast<__node_base_pointer>(__root())));
1136
1137 using __reference = decltype(*__first);
1138
1139 for (; __first != __last; ++__first) {
1140 std::__try_key_extraction<key_type>(
1141 [this, &__max_node](const key_type& __key, __reference&& __val) {
1142 if (value_comp()(__max_node->__get_value(), __key)) { // __key > __max_node
1143 __node_holder __nd = __construct_node(std::forward<__reference>(__val));
1144 __insert_node_at(static_cast<__end_node_pointer>(__max_node),
1145 __max_node->__right_,
1146 static_cast<__node_base_pointer>(__nd.get()));
1147 __max_node = __nd.release();
1148 } else {
1149 auto [__parent, __child] = __find_equal(__key);
1150 if (__child == nullptr) {
1151 __node_holder __nd = __construct_node(std::forward<__reference>(__val));
1152 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd.release()));
1153 }
1154 }
1155 },
1156 [this, &__max_node](__reference&& __val) {
1157 __node_holder __nd = __construct_node(std::forward<__reference>(__val));
1158 if (value_comp()(__max_node->__get_value(), __nd->__get_value())) { // __node > __max_node
1159 __insert_node_at(static_cast<__end_node_pointer>(__max_node),
1160 __max_node->__right_,
1161 static_cast<__node_base_pointer>(__nd.get()));
1162 __max_node = __nd.release();
1163 } else {
1164 auto [__parent, __child] = __find_equal(__nd->__get_value());
1165 if (__child == nullptr) {
1166 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd.release()));
1167 }
1168 }
1169 },
1170 *__first);
1171 }
10371172 }
10381173
1039 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __node_assign_unique(const value_type& __v, __node_pointer __dest);
1040
1041 _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(__node_pointer __nd);
1042 _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
1043
10441174 _LIBCPP_HIDE_FROM_ABI iterator __remove_node_pointer(__node_pointer) _NOEXCEPT;
10451175
10461176#if _LIBCPP_STD_VER >= 17
......@@ -1048,15 +1178,15 @@ public:
10481178 _LIBCPP_HIDE_FROM_ABI _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
10491179 template <class _NodeHandle>
10501180 _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&);
1051 template <class _Tree>
1052 _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_unique(_Tree& __source);
1181 template <class _Comp2>
1182 _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_unique(__tree<_Tp, _Comp2, _Allocator>& __source);
10531183
10541184 template <class _NodeHandle>
10551185 _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(_NodeHandle&&);
10561186 template <class _NodeHandle>
10571187 _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&);
1058 template <class _Tree>
1059 _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_multi(_Tree& __source);
1188 template <class _Comp2>
1189 _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_multi(__tree<_Tp, _Comp2, _Allocator>& __source);
10601190
10611191 template <class _NodeHandle>
10621192 _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(key_type const&);
......@@ -1075,41 +1205,157 @@ public:
10751205 __insert_node_at(__end_node_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node) _NOEXCEPT;
10761206
10771207 template <class _Key>
1078 _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __v);
1208 _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __key) {
1209 auto [__, __match] = __find_equal(__key);
1210 if (__match == nullptr)
1211 return end();
1212 return iterator(static_cast<__node_pointer>(__match));
1213 }
1214
10791215 template <class _Key>
1080 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __v) const;
1216 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __key) const {
1217 auto [__, __match] = __find_equal(__key);
1218 if (__match == nullptr)
1219 return end();
1220 return const_iterator(static_cast<__node_pointer>(__match));
1221 }
10811222
10821223 template <class _Key>
10831224 _LIBCPP_HIDE_FROM_ABI size_type __count_unique(const _Key& __k) const;
10841225 template <class _Key>
10851226 _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const;
10861227
1228 template <bool _LowerBound, class _Key>
1229 _LIBCPP_HIDE_FROM_ABI __end_node_pointer __lower_upper_bound_unique_impl(const _Key& __v) const {
1230 auto __rt = __root();
1231 auto __result = __end_node();
1232 auto __comp = __lazy_synth_three_way_comparator<_Compare, _Key, value_type>(value_comp());
1233 while (__rt != nullptr) {
1234 auto __comp_res = __comp(__v, __rt->__get_value());
1235
1236 if (__comp_res.__less()) {
1237 __result = static_cast<__end_node_pointer>(__rt);
1238 __rt = static_cast<__node_pointer>(__rt->__left_);
1239 } else if (__comp_res.__greater()) {
1240 __rt = static_cast<__node_pointer>(__rt->__right_);
1241 } else if _LIBCPP_CONSTEXPR (_LowerBound) {
1242 return static_cast<__end_node_pointer>(__rt);
1243 } else {
1244 return __rt->__right_ ? static_cast<__end_node_pointer>(std::__tree_min(__rt->__right_)) : __result;
1245 }
1246 }
1247 return __result;
1248 }
1249
1250 // Compatibility escape hatch for comparators that are not strict weak orderings. This
1251 // can be removed for the LLVM 23 release.
1252#if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
10871253 template <class _Key>
1088 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _Key& __v) {
1089 return __lower_bound(__v, __root(), __end_node());
1254 _LIBCPP_HIDE_FROM_ABI __end_node_pointer __lower_bound_unique_compat_impl(const _Key& __v) const {
1255 auto __rt = __root();
1256 auto __result = __end_node();
1257 while (__rt != nullptr) {
1258 if (!value_comp()(__rt->__get_value(), __v)) {
1259 __result = std::__static_fancy_pointer_cast<__end_node_pointer>(__rt);
1260 __rt = std::__static_fancy_pointer_cast<__node_pointer>(__rt->__left_);
1261 } else {
1262 __rt = std::__static_fancy_pointer_cast<__node_pointer>(__rt->__right_);
1263 }
1264 }
1265 return __result;
10901266 }
1267
10911268 template <class _Key>
1092 _LIBCPP_HIDE_FROM_ABI iterator __lower_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result);
1269 _LIBCPP_HIDE_FROM_ABI __end_node_pointer __upper_bound_unique_compat_impl(const _Key& __v) const {
1270 auto __rt = __root();
1271 auto __result = __end_node();
1272 while (__rt != nullptr) {
1273 if (value_comp()(__v, __rt->__get_value())) {
1274 __result = std::__static_fancy_pointer_cast<__end_node_pointer>(__rt);
1275 __rt = std::__static_fancy_pointer_cast<__node_pointer>(__rt->__left_);
1276 } else {
1277 __rt = std::__static_fancy_pointer_cast<__node_pointer>(__rt->__right_);
1278 }
1279 }
1280 return __result;
1281 }
1282#endif // _LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND
1283
10931284 template <class _Key>
1094 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _Key& __v) const {
1095 return __lower_bound(__v, __root(), __end_node());
1285 _LIBCPP_HIDE_FROM_ABI iterator __lower_bound_unique(const _Key& __v) {
1286#if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
1287 return iterator(__lower_bound_unique_compat_impl(__v));
1288#else
1289 return iterator(__lower_upper_bound_unique_impl<true>(__v));
1290#endif
10961291 }
1292
1293 template <class _Key>
1294 _LIBCPP_HIDE_FROM_ABI const_iterator __lower_bound_unique(const _Key& __v) const {
1295#if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
1296 return const_iterator(__lower_bound_unique_compat_impl(__v));
1297#else
1298 return const_iterator(__lower_upper_bound_unique_impl<true>(__v));
1299#endif
1300 }
1301
1302 template <class _Key>
1303 _LIBCPP_HIDE_FROM_ABI iterator __upper_bound_unique(const _Key& __v) {
1304#if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
1305 return iterator(__upper_bound_unique_compat_impl(__v));
1306#else
1307 return iterator(__lower_upper_bound_unique_impl<false>(__v));
1308#endif
1309 }
1310
1311 template <class _Key>
1312 _LIBCPP_HIDE_FROM_ABI const_iterator __upper_bound_unique(const _Key& __v) const {
1313#if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
1314 return iterator(__upper_bound_unique_compat_impl(__v));
1315#else
1316 return iterator(__lower_upper_bound_unique_impl<false>(__v));
1317#endif
1318 }
1319
1320private:
1321 template <class _Key>
1322 _LIBCPP_HIDE_FROM_ABI iterator
1323 __lower_bound_multi(const _Key& __v, __node_pointer __root, __end_node_pointer __result);
1324
10971325 template <class _Key>
10981326 _LIBCPP_HIDE_FROM_ABI const_iterator
1099 __lower_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) const;
1327 __lower_bound_multi(const _Key& __v, __node_pointer __root, __end_node_pointer __result) const;
1328
1329public:
11001330 template <class _Key>
1101 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _Key& __v) {
1102 return __upper_bound(__v, __root(), __end_node());
1331 _LIBCPP_HIDE_FROM_ABI iterator __lower_bound_multi(const _Key& __v) {
1332 return __lower_bound_multi(__v, __root(), __end_node());
11031333 }
11041334 template <class _Key>
1105 _LIBCPP_HIDE_FROM_ABI iterator __upper_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result);
1335 _LIBCPP_HIDE_FROM_ABI const_iterator __lower_bound_multi(const _Key& __v) const {
1336 return __lower_bound_multi(__v, __root(), __end_node());
1337 }
1338
1339 template <class _Key>
1340 _LIBCPP_HIDE_FROM_ABI iterator __upper_bound_multi(const _Key& __v) {
1341 return __upper_bound_multi(__v, __root(), __end_node());
1342 }
1343
11061344 template <class _Key>
1107 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _Key& __v) const {
1108 return __upper_bound(__v, __root(), __end_node());
1345 _LIBCPP_HIDE_FROM_ABI const_iterator __upper_bound_multi(const _Key& __v) const {
1346 return __upper_bound_multi(__v, __root(), __end_node());
11091347 }
1348
1349private:
1350 template <class _Key>
1351 _LIBCPP_HIDE_FROM_ABI iterator
1352 __upper_bound_multi(const _Key& __v, __node_pointer __root, __end_node_pointer __result);
1353
11101354 template <class _Key>
11111355 _LIBCPP_HIDE_FROM_ABI const_iterator
1112 __upper_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) const;
1356 __upper_bound_multi(const _Key& __v, __node_pointer __root, __end_node_pointer __result) const;
1357
1358public:
11131359 template <class _Key>
11141360 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> __equal_range_unique(const _Key& __k);
11151361 template <class _Key>
......@@ -1120,22 +1366,24 @@ public:
11201366 template <class _Key>
11211367 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> __equal_range_multi(const _Key& __k) const;
11221368
1123 typedef __tree_node_destructor<__node_allocator> _Dp;
1124 typedef unique_ptr<__node, _Dp> __node_holder;
1369 using _Dp _LIBCPP_NODEBUG = __tree_node_destructor<__node_allocator>;
1370 using __node_holder _LIBCPP_NODEBUG = unique_ptr<__node, _Dp>;
11251371
11261372 _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT;
11271373
11281374 // FIXME: Make this function const qualified. Unfortunately doing so
11291375 // breaks existing code which uses non-const callable comparators.
11301376 template <class _Key>
1131 _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_equal(__end_node_pointer& __parent, const _Key& __v);
1377 _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&> __find_equal(const _Key& __v);
1378
11321379 template <class _Key>
1133 _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_equal(__end_node_pointer& __parent, const _Key& __v) const {
1134 return const_cast<__tree*>(this)->__find_equal(__parent, __v);
1380 _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&> __find_equal(const _Key& __v) const {
1381 return const_cast<__tree*>(this)->__find_equal(__v);
11351382 }
1383
11361384 template <class _Key>
1137 _LIBCPP_HIDE_FROM_ABI __node_base_pointer&
1138 __find_equal(const_iterator __hint, __end_node_pointer& __parent, __node_base_pointer& __dummy, const _Key& __v);
1385 _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&>
1386 __find_equal(const_iterator __hint, __node_base_pointer& __dummy, const _Key& __v);
11391387
11401388 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __tree& __t) {
11411389 __copy_assign_alloc(__t, integral_constant<bool, __node_traits::propagate_on_container_copy_assignment::value>());
......@@ -1160,7 +1408,7 @@ private:
11601408 _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&&... __args);
11611409
11621410 // TODO: Make this _LIBCPP_HIDE_FROM_ABI
1163 _LIBCPP_HIDDEN void destroy(__node_pointer __nd) _NOEXCEPT;
1411 _LIBCPP_HIDDEN void destroy(__node_pointer __nd) _NOEXCEPT { (__tree_deleter(__node_alloc_))(__nd); }
11641412
11651413 _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, false_type);
11661414 _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, true_type) _NOEXCEPT_(
......@@ -1178,7 +1426,7 @@ private:
11781426 }
11791427 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
11801428
1181 template <class _From, class _ValueT = _Tp, __enable_if_t<__is_tree_value_type<_ValueT>::value, int> = 0>
1429 template <class _From, class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0>
11821430 _LIBCPP_HIDE_FROM_ABI static void __assign_value(__get_node_value_type_t<value_type>& __lhs, _From&& __rhs) {
11831431 using __key_type = __remove_const_t<typename value_type::first_type>;
11841432
......@@ -1188,166 +1436,203 @@ private:
11881436 __lhs.second = std::forward<_From>(__rhs).second;
11891437 }
11901438
1191 template <class _To, class _From, class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type<_ValueT>::value, int> = 0>
1439 template <class _To, class _From, class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0>
11921440 _LIBCPP_HIDE_FROM_ABI static void __assign_value(_To& __lhs, _From&& __rhs) {
11931441 __lhs = std::forward<_From>(__rhs);
11941442 }
11951443
1196 struct _DetachedTreeCache {
1197 _LIBCPP_HIDE_FROM_ABI explicit _DetachedTreeCache(__tree* __t) _NOEXCEPT
1198 : __t_(__t),
1199 __cache_root_(__detach_from_tree(__t)) {
1200 __advance();
1444 class __tree_deleter {
1445 __node_allocator& __alloc_;
1446
1447 public:
1448 using pointer = __node_pointer;
1449
1450 _LIBCPP_HIDE_FROM_ABI __tree_deleter(__node_allocator& __alloc) : __alloc_(__alloc) {}
1451
1452#ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
1453 _LIBCPP_HIDE_FROM_ABI
1454#endif
1455 void
1456 operator()(__node_pointer __ptr) {
1457 if (!__ptr)
1458 return;
1459
1460 (*this)(static_cast<__node_pointer>(__ptr->__left_));
1461
1462 auto __right = __ptr->__right_;
1463
1464 __node_traits::destroy(__alloc_, std::addressof(__ptr->__get_value()));
1465 __node_traits::deallocate(__alloc_, __ptr, 1);
1466
1467 (*this)(static_cast<__node_pointer>(__right));
12011468 }
1469 };
1470
1471 // This copy construction will always produce a correct red-black-tree assuming the incoming tree is correct, since we
1472 // copy the exact structure 1:1. Since this is for copy construction _only_ we know that we get a correct tree. If we
1473 // didn't get a correct tree, the invariants of __tree are broken and we have a much bigger problem than an improperly
1474 // balanced tree.
1475 template <class _NodeConstructor>
1476#ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
1477 _LIBCPP_HIDE_FROM_ABI
1478#endif
1479 __node_pointer __construct_from_tree(__node_pointer __src, _NodeConstructor __construct) {
1480 if (!__src)
1481 return nullptr;
12021482
1203 _LIBCPP_HIDE_FROM_ABI __node_pointer __get() const _NOEXCEPT { return __cache_elem_; }
1483 __node_holder __new_node = __construct(__src->__get_value());
12041484
1205 _LIBCPP_HIDE_FROM_ABI void __advance() _NOEXCEPT {
1206 __cache_elem_ = __cache_root_;
1207 if (__cache_root_) {
1208 __cache_root_ = __detach_next(__cache_root_);
1209 }
1485 unique_ptr<__node, __tree_deleter> __left(
1486 __construct_from_tree(static_cast<__node_pointer>(__src->__left_), __construct), __node_alloc_);
1487 __node_pointer __right = __construct_from_tree(static_cast<__node_pointer>(__src->__right_), __construct);
1488
1489 __node_pointer __new_node_ptr = __new_node.release();
1490
1491 __new_node_ptr->__is_black_ = __src->__is_black_;
1492 __new_node_ptr->__left_ = static_cast<__node_base_pointer>(__left.release());
1493 __new_node_ptr->__right_ = static_cast<__node_base_pointer>(__right);
1494 if (__new_node_ptr->__left_)
1495 __new_node_ptr->__left_->__parent_ = static_cast<__end_node_pointer>(__new_node_ptr);
1496 if (__new_node_ptr->__right_)
1497 __new_node_ptr->__right_->__parent_ = static_cast<__end_node_pointer>(__new_node_ptr);
1498 return __new_node_ptr;
1499 }
1500
1501 _LIBCPP_HIDE_FROM_ABI __node_pointer __copy_construct_tree(__node_pointer __src) {
1502 return __construct_from_tree(__src, [this](const value_type& __val) { return __construct_node(__val); });
1503 }
1504
1505 template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0>
1506 _LIBCPP_HIDE_FROM_ABI __node_pointer __move_construct_tree(__node_pointer __src) {
1507 return __construct_from_tree(__src, [this](value_type& __val) {
1508 return __construct_node(const_cast<key_type&&>(__val.first), std::move(__val.second));
1509 });
1510 }
1511
1512 template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0>
1513 _LIBCPP_HIDE_FROM_ABI __node_pointer __move_construct_tree(__node_pointer __src) {
1514 return __construct_from_tree(__src, [this](value_type& __val) { return __construct_node(std::move(__val)); });
1515 }
1516
1517 template <class _Assignment, class _ConstructionAlg>
1518 // This copy assignment will always produce a correct red-black-tree assuming the incoming tree is correct, since our
1519 // own tree is a red-black-tree and the incoming tree is a red-black-tree. The invariants of a red-black-tree are
1520 // temporarily not met until all of the incoming red-black tree is copied.
1521#ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
1522 _LIBCPP_HIDE_FROM_ABI
1523#endif
1524 __node_pointer __assign_from_tree(
1525 __node_pointer __dest, __node_pointer __src, _Assignment __assign, _ConstructionAlg __construct_subtree) {
1526 if (!__src) {
1527 destroy(__dest);
1528 return nullptr;
12101529 }
12111530
1212 _LIBCPP_HIDE_FROM_ABI ~_DetachedTreeCache() {
1213 __t_->destroy(__cache_elem_);
1214 if (__cache_root_) {
1215 while (__cache_root_->__parent_ != nullptr)
1216 __cache_root_ = static_cast<__node_pointer>(__cache_root_->__parent_);
1217 __t_->destroy(__cache_root_);
1218 }
1531 __assign(__dest->__get_value(), __src->__get_value());
1532 __dest->__is_black_ = __src->__is_black_;
1533
1534 // If we already have a left node in the destination tree, reuse it and copy-assign recursively
1535 if (__dest->__left_) {
1536 __dest->__left_ = static_cast<__node_base_pointer>(__assign_from_tree(
1537 static_cast<__node_pointer>(__dest->__left_),
1538 static_cast<__node_pointer>(__src->__left_),
1539 __assign,
1540 __construct_subtree));
1541
1542 // Otherwise, we must create new nodes; copy-construct from here on
1543 } else if (__src->__left_) {
1544 auto __new_left = __construct_subtree(static_cast<__node_pointer>(__src->__left_));
1545 __dest->__left_ = static_cast<__node_base_pointer>(__new_left);
1546 __new_left->__parent_ = static_cast<__end_node_pointer>(__dest);
12191547 }
12201548
1221 _DetachedTreeCache(_DetachedTreeCache const&) = delete;
1222 _DetachedTreeCache& operator=(_DetachedTreeCache const&) = delete;
1549 // Identical to the left case above, just for the right nodes
1550 if (__dest->__right_) {
1551 __dest->__right_ = static_cast<__node_base_pointer>(__assign_from_tree(
1552 static_cast<__node_pointer>(__dest->__right_),
1553 static_cast<__node_pointer>(__src->__right_),
1554 __assign,
1555 __construct_subtree));
1556 } else if (__src->__right_) {
1557 auto __new_right = __construct_subtree(static_cast<__node_pointer>(__src->__right_));
1558 __dest->__right_ = static_cast<__node_base_pointer>(__new_right);
1559 __new_right->__parent_ = static_cast<__end_node_pointer>(__dest);
1560 }
12231561
1224 private:
1225 _LIBCPP_HIDE_FROM_ABI static __node_pointer __detach_from_tree(__tree* __t) _NOEXCEPT;
1226 _LIBCPP_HIDE_FROM_ABI static __node_pointer __detach_next(__node_pointer) _NOEXCEPT;
1562 return __dest;
1563 }
12271564
1228 __tree* __t_;
1229 __node_pointer __cache_root_;
1230 __node_pointer __cache_elem_;
1231 };
1232};
1565 _LIBCPP_HIDE_FROM_ABI __node_pointer __copy_assign_tree(__node_pointer __dest, __node_pointer __src) {
1566 return __assign_from_tree(
1567 __dest,
1568 __src,
1569 [](value_type& __lhs, const value_type& __rhs) { __assign_value(__lhs, __rhs); },
1570 [this](__node_pointer __nd) { return __copy_construct_tree(__nd); });
1571 }
12331572
1234template <class _Tp, class _Compare, class _Allocator>
1235__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp) _NOEXCEPT_(
1236 is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_copy_constructible<value_compare>::value)
1237 : __size_(0), __value_comp_(__comp) {
1238 __begin_node() = __end_node();
1239}
1573 _LIBCPP_HIDE_FROM_ABI __node_pointer __move_assign_tree(__node_pointer __dest, __node_pointer __src) {
1574 return __assign_from_tree(
1575 __dest,
1576 __src,
1577 [](value_type& __lhs, value_type& __rhs) { __assign_value(__lhs, std::move(__rhs)); },
1578 [this](__node_pointer __nd) { return __move_construct_tree(__nd); });
1579 }
12401580
1241template <class _Tp, class _Compare, class _Allocator>
1242__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
1243 : __begin_node_(), __node_alloc_(__node_allocator(__a)), __size_(0) {
1244 __begin_node() = __end_node();
1245}
1581 friend struct __specialized_algorithm<_Algorithm::__for_each, __single_range<__tree> >;
1582};
12461583
1584#if _LIBCPP_STD_VER >= 14
12471585template <class _Tp, class _Compare, class _Allocator>
1248__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp, const allocator_type& __a)
1249 : __begin_node_(), __node_alloc_(__node_allocator(__a)), __size_(0), __value_comp_(__comp) {
1250 __begin_node() = __end_node();
1251}
1586struct __specialized_algorithm<_Algorithm::__for_each, __single_range<__tree<_Tp, _Compare, _Allocator> > > {
1587 static const bool __has_algorithm = true;
12521588
1253// Precondition: size() != 0
1254template <class _Tp, class _Compare, class _Allocator>
1255typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1256__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_from_tree(__tree* __t) _NOEXCEPT {
1257 __node_pointer __cache = static_cast<__node_pointer>(__t->__begin_node());
1258 __t->__begin_node() = __t->__end_node();
1259 __t->__end_node()->__left_->__parent_ = nullptr;
1260 __t->__end_node()->__left_ = nullptr;
1261 __t->size() = 0;
1262 // __cache->__left_ == nullptr
1263 if (__cache->__right_ != nullptr)
1264 __cache = static_cast<__node_pointer>(__cache->__right_);
1265 // __cache->__left_ == nullptr
1266 // __cache->__right_ == nullptr
1267 return __cache;
1268}
1589 using __node_pointer _LIBCPP_NODEBUG = typename __tree<_Tp, _Compare, _Allocator>::__node_pointer;
12691590
1270// Precondition: __cache != nullptr
1271// __cache->left_ == nullptr
1272// __cache->right_ == nullptr
1273// This is no longer a red-black tree
1274template <class _Tp, class _Compare, class _Allocator>
1275typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
1276__tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_next(__node_pointer __cache) _NOEXCEPT {
1277 if (__cache->__parent_ == nullptr)
1278 return nullptr;
1279 if (std::__tree_is_left_child(static_cast<__node_base_pointer>(__cache))) {
1280 __cache->__parent_->__left_ = nullptr;
1281 __cache = static_cast<__node_pointer>(__cache->__parent_);
1282 if (__cache->__right_ == nullptr)
1283 return __cache;
1284 return static_cast<__node_pointer>(std::__tree_leaf(__cache->__right_));
1285 }
1286 // __cache is right child
1287 __cache->__parent_unsafe()->__right_ = nullptr;
1288 __cache = static_cast<__node_pointer>(__cache->__parent_);
1289 if (__cache->__left_ == nullptr)
1290 return __cache;
1291 return static_cast<__node_pointer>(std::__tree_leaf(__cache->__left_));
1292}
1591 template <class _Tree, class _Func, class _Proj>
1592 _LIBCPP_HIDE_FROM_ABI static auto operator()(_Tree&& __range, _Func __func, _Proj __proj) {
1593 if (__range.size() != 0)
1594 std::__tree_iterate_from_root<__copy_cvref_t<_Tree, typename __remove_cvref_t<_Tree>::value_type>>(
1595 [](__node_pointer) { return false; }, __range.__root(), __func, __proj);
1596 return std::make_pair(__range.end(), std::move(__func));
1597 }
1598};
1599#endif
12931600
12941601template <class _Tp, class _Compare, class _Allocator>
12951602__tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t) {
1296 if (this != std::addressof(__t)) {
1297 value_comp() = __t.value_comp();
1298 __copy_assign_alloc(__t);
1299 __assign_multi(__t.begin(), __t.end());
1300 }
1301 return *this;
1302}
1603 if (this == std::addressof(__t))
1604 return *this;
13031605
1304template <class _Tp, class _Compare, class _Allocator>
1305template <class _ForwardIterator>
1306void __tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _ForwardIterator __last) {
1307 typedef iterator_traits<_ForwardIterator> _ITraits;
1308 typedef typename _ITraits::value_type _ItValueType;
1309 static_assert(
1310 is_same<_ItValueType, value_type>::value, "__assign_unique may only be called with the containers value type");
1311 static_assert(
1312 __has_forward_iterator_category<_ForwardIterator>::value, "__assign_unique requires a forward iterator");
1313 if (size() != 0) {
1314 _DetachedTreeCache __cache(this);
1315 for (; __cache.__get() != nullptr && __first != __last; ++__first) {
1316 if (__node_assign_unique(*__first, __cache.__get()).second)
1317 __cache.__advance();
1318 }
1319 }
1320 for (; __first != __last; ++__first)
1321 __emplace_unique(*__first);
1322}
1606 value_comp() = __t.value_comp();
1607 __copy_assign_alloc(__t);
13231608
1324template <class _Tp, class _Compare, class _Allocator>
1325template <class _InputIterator>
1326void __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last) {
1327 typedef iterator_traits<_InputIterator> _ITraits;
1328 typedef typename _ITraits::value_type _ItValueType;
1329 static_assert(
1330 is_same<_ItValueType, value_type>::value, "__assign_multi may only be called with the containers value_type");
1331 if (size() != 0) {
1332 _DetachedTreeCache __cache(this);
1333 for (; __cache.__get() && __first != __last; ++__first) {
1334 __assign_value(__cache.__get()->__value_, *__first);
1335 __node_insert_multi(__cache.__get());
1336 __cache.__advance();
1337 }
1609 if (__size_ != 0) {
1610 *__root_ptr() = static_cast<__node_base_pointer>(__copy_assign_tree(__root(), __t.__root()));
1611 } else {
1612 *__root_ptr() = static_cast<__node_base_pointer>(__copy_construct_tree(__t.__root()));
1613 if (__root())
1614 __root()->__parent_ = __end_node();
13381615 }
1339 const_iterator __e = end();
1340 for (; __first != __last; ++__first)
1341 __emplace_hint_multi(__e, *__first);
1616 __begin_node_ =
1617 __end_node()->__left_ ? static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_)) : __end_node();
1618 __size_ = __t.size();
1619
1620 return *this;
13421621}
13431622
13441623template <class _Tp, class _Compare, class _Allocator>
13451624__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
1346 : __begin_node_(),
1625 : __begin_node_(__end_node()),
13471626 __node_alloc_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())),
13481627 __size_(0),
13491628 __value_comp_(__t.value_comp()) {
1350 __begin_node() = __end_node();
1629 if (__t.size() == 0)
1630 return;
1631
1632 *__root_ptr() = static_cast<__node_base_pointer>(__copy_construct_tree(__t.__root()));
1633 __root()->__parent_ = __end_node();
1634 __begin_node_ = static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_));
1635 __size_ = __t.size();
13511636}
13521637
13531638template <class _Tp, class _Compare, class _Allocator>
......@@ -1358,33 +1643,38 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_(
13581643 __node_alloc_(std::move(__t.__node_alloc_)),
13591644 __size_(__t.__size_),
13601645 __value_comp_(std::move(__t.__value_comp_)) {
1361 if (size() == 0)
1362 __begin_node() = __end_node();
1646 if (__size_ == 0)
1647 __begin_node_ = __end_node();
13631648 else {
13641649 __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
1365 __t.__begin_node() = __t.__end_node();
1650 __t.__begin_node_ = __t.__end_node();
13661651 __t.__end_node()->__left_ = nullptr;
1367 __t.size() = 0;
1652 __t.__size_ = 0;
13681653 }
13691654}
13701655
13711656template <class _Tp, class _Compare, class _Allocator>
13721657__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
1373 : __node_alloc_(__node_allocator(__a)), __size_(0), __value_comp_(std::move(__t.value_comp())) {
1658 : __begin_node_(__end_node()),
1659 __node_alloc_(__node_allocator(__a)),
1660 __size_(0),
1661 __value_comp_(std::move(__t.value_comp())) {
1662 if (__t.size() == 0)
1663 return;
13741664 if (__a == __t.__alloc()) {
1375 if (__t.size() == 0)
1376 __begin_node() = __end_node();
1377 else {
1378 __begin_node() = __t.__begin_node();
1379 __end_node()->__left_ = __t.__end_node()->__left_;
1380 __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
1381 size() = __t.size();
1382 __t.__begin_node() = __t.__end_node();
1383 __t.__end_node()->__left_ = nullptr;
1384 __t.size() = 0;
1385 }
1665 __begin_node_ = __t.__begin_node_;
1666 __end_node()->__left_ = __t.__end_node()->__left_;
1667 __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
1668 __size_ = __t.__size_;
1669 __t.__begin_node_ = __t.__end_node();
1670 __t.__end_node()->__left_ = nullptr;
1671 __t.__size_ = 0;
13861672 } else {
1387 __begin_node() = __end_node();
1673 *__root_ptr() = static_cast<__node_base_pointer>(__move_construct_tree(__t.__root()));
1674 __root()->__parent_ = __end_node();
1675 __begin_node_ = static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_));
1676 __size_ = __t.size();
1677 __t.clear(); // Ensure that __t is in a valid state after moving out the keys
13881678 }
13891679}
13901680
......@@ -1397,61 +1687,33 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
13971687 __move_assign_alloc(__t);
13981688 __size_ = __t.__size_;
13991689 __value_comp_ = std::move(__t.__value_comp_);
1400 if (size() == 0)
1401 __begin_node() = __end_node();
1690 if (__size_ == 0)
1691 __begin_node_ = __end_node();
14021692 else {
14031693 __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node());
1404 __t.__begin_node() = __t.__end_node();
1694 __t.__begin_node_ = __t.__end_node();
14051695 __t.__end_node()->__left_ = nullptr;
1406 __t.size() = 0;
1696 __t.__size_ = 0;
14071697 }
14081698}
14091699
14101700template <class _Tp, class _Compare, class _Allocator>
14111701void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
1412 if (__node_alloc() == __t.__node_alloc())
1702 if (__node_alloc() == __t.__node_alloc()) {
14131703 __move_assign(__t, true_type());
1414 else {
1415 value_comp() = std::move(__t.value_comp());
1416 const_iterator __e = end();
1417 if (size() != 0) {
1418 _DetachedTreeCache __cache(this);
1419 while (__cache.__get() != nullptr && __t.size() != 0) {
1420 __assign_value(__cache.__get()->__value_, std::move(__t.remove(__t.begin())->__value_));
1421 __node_insert_multi(__cache.__get());
1422 __cache.__advance();
1423 }
1424 }
1425 while (__t.size() != 0) {
1426 __insert_multi_from_orphaned_node(__e, std::move(__t.remove(__t.begin())->__value_));
1704 } else {
1705 value_comp() = std::move(__t.value_comp());
1706 if (__size_ != 0) {
1707 *__root_ptr() = static_cast<__node_base_pointer>(__move_assign_tree(__root(), __t.__root()));
1708 } else {
1709 *__root_ptr() = static_cast<__node_base_pointer>(__move_construct_tree(__t.__root()));
1710 if (__root())
1711 __root()->__parent_ = __end_node();
14271712 }
1428 }
1429}
1430
1431template <class _Tp, class _Compare, class _Allocator>
1432__tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
1433 _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
1434 ((__node_traits::propagate_on_container_move_assignment::value &&
1435 is_nothrow_move_assignable<__node_allocator>::value) ||
1436 allocator_traits<__node_allocator>::is_always_equal::value)) {
1437 __move_assign(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
1438 return *this;
1439}
1440
1441template <class _Tp, class _Compare, class _Allocator>
1442__tree<_Tp, _Compare, _Allocator>::~__tree() {
1443 static_assert(is_copy_constructible<value_compare>::value, "Comparator must be copy-constructible.");
1444 destroy(__root());
1445}
1446
1447template <class _Tp, class _Compare, class _Allocator>
1448void __tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT {
1449 if (__nd != nullptr) {
1450 destroy(static_cast<__node_pointer>(__nd->__left_));
1451 destroy(static_cast<__node_pointer>(__nd->__right_));
1452 __node_allocator& __na = __node_alloc();
1453 __node_traits::destroy(__na, std::addressof(__nd->__value_));
1454 __node_traits::deallocate(__na, __nd, 1);
1713 __begin_node_ =
1714 __end_node()->__left_ ? static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_)) : __end_node();
1715 __size_ = __t.size();
1716 __t.clear(); // Ensure that __t is in a valid state after moving out the keys
14551717 }
14561718}
14571719
......@@ -1470,12 +1732,12 @@ void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
14701732 std::__swap_allocator(__node_alloc(), __t.__node_alloc());
14711733 swap(__size_, __t.__size_);
14721734 swap(__value_comp_, __t.__value_comp_);
1473 if (size() == 0)
1474 __begin_node() = __end_node();
1735 if (__size_ == 0)
1736 __begin_node_ = __end_node();
14751737 else
14761738 __end_node()->__left_->__parent_ = __end_node();
1477 if (__t.size() == 0)
1478 __t.__begin_node() = __t.__end_node();
1739 if (__t.__size_ == 0)
1740 __t.__begin_node_ = __t.__end_node();
14791741 else
14801742 __t.__end_node()->__left_->__parent_ = __t.__end_node();
14811743}
......@@ -1483,8 +1745,8 @@ void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
14831745template <class _Tp, class _Compare, class _Allocator>
14841746void __tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT {
14851747 destroy(__root());
1486 size() = 0;
1487 __begin_node() = __end_node();
1748 __size_ = 0;
1749 __begin_node_ = __end_node();
14881750 __end_node()->__left_ = nullptr;
14891751}
14901752
......@@ -1497,7 +1759,7 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__end_node_pointer& __parent,
14971759 __node_pointer __nd = __root();
14981760 if (__nd != nullptr) {
14991761 while (true) {
1500 if (value_comp()(__nd->__value_, __v)) {
1762 if (value_comp()(__nd->__get_value(), __v)) {
15011763 if (__nd->__right_ != nullptr)
15021764 __nd = static_cast<__node_pointer>(__nd->__right_);
15031765 else {
......@@ -1527,7 +1789,7 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__end_node_pointer& __parent
15271789 __node_pointer __nd = __root();
15281790 if (__nd != nullptr) {
15291791 while (true) {
1530 if (value_comp()(__v, __nd->__value_)) {
1792 if (value_comp()(__v, __nd->__get_value())) {
15311793 if (__nd->__left_ != nullptr)
15321794 __nd = static_cast<__node_pointer>(__nd->__left_);
15331795 else {
......@@ -1578,92 +1840,91 @@ typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Co
15781840 return __find_leaf_low(__parent, __v);
15791841}
15801842
1581// Find place to insert if __v doesn't exist
1582// Set __parent to parent of null leaf
1583// Return reference to null leaf
1584// If __v exists, set parent to node of __v and return reference to node of __v
1843// Find __v
1844// If __v exists, return the parent of the node of __v and a reference to the pointer to the node of __v.
1845// If __v doesn't exist, return the parent of the null leaf and a reference to the pointer to the null leaf.
15851846template <class _Tp, class _Compare, class _Allocator>
15861847template <class _Key>
1587typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1588__tree<_Tp, _Compare, _Allocator>::__find_equal(__end_node_pointer& __parent, const _Key& __v) {
1589 __node_pointer __nd = __root();
1590 __node_base_pointer* __nd_ptr = __root_ptr();
1591 if (__nd != nullptr) {
1592 while (true) {
1593 if (value_comp()(__v, __nd->__value_)) {
1594 if (__nd->__left_ != nullptr) {
1595 __nd_ptr = std::addressof(__nd->__left_);
1596 __nd = static_cast<__node_pointer>(__nd->__left_);
1597 } else {
1598 __parent = static_cast<__end_node_pointer>(__nd);
1599 return __parent->__left_;
1600 }
1601 } else if (value_comp()(__nd->__value_, __v)) {
1602 if (__nd->__right_ != nullptr) {
1603 __nd_ptr = std::addressof(__nd->__right_);
1604 __nd = static_cast<__node_pointer>(__nd->__right_);
1605 } else {
1606 __parent = static_cast<__end_node_pointer>(__nd);
1607 return __nd->__right_;
1608 }
1609 } else {
1610 __parent = static_cast<__end_node_pointer>(__nd);
1611 return *__nd_ptr;
1612 }
1848_LIBCPP_HIDE_FROM_ABI pair<typename __tree<_Tp, _Compare, _Allocator>::__end_node_pointer,
1849 typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&>
1850__tree<_Tp, _Compare, _Allocator>::__find_equal(const _Key& __v) {
1851 using _Pair = pair<__end_node_pointer, __node_base_pointer&>;
1852
1853 __node_pointer __nd = __root();
1854
1855 if (__nd == nullptr) {
1856 auto __end = __end_node();
1857 return _Pair(__end, __end->__left_);
1858 }
1859
1860 __node_base_pointer* __node_ptr = __root_ptr();
1861 auto&& __transparent = std::__as_transparent<_Key>(value_comp());
1862 auto __comp =
1863 __lazy_synth_three_way_comparator<__make_transparent_t<_Key, _Compare>, _Key, value_type>(__transparent);
1864
1865 while (true) {
1866 auto __comp_res = __comp(__v, __nd->__get_value());
1867
1868 if (__comp_res.__less()) {
1869 if (__nd->__left_ == nullptr)
1870 return _Pair(static_cast<__end_node_pointer>(__nd), __nd->__left_);
1871
1872 __node_ptr = std::addressof(__nd->__left_);
1873 __nd = static_cast<__node_pointer>(__nd->__left_);
1874 } else if (__comp_res.__greater()) {
1875 if (__nd->__right_ == nullptr)
1876 return _Pair(static_cast<__end_node_pointer>(__nd), __nd->__right_);
1877
1878 __node_ptr = std::addressof(__nd->__right_);
1879 __nd = static_cast<__node_pointer>(__nd->__right_);
1880 } else {
1881 return _Pair(static_cast<__end_node_pointer>(__nd), *__node_ptr);
16131882 }
16141883 }
1615 __parent = __end_node();
1616 return __parent->__left_;
16171884}
16181885
1619// Find place to insert if __v doesn't exist
1886// Find __v
16201887// First check prior to __hint.
16211888// Next check after __hint.
16221889// Next do O(log N) search.
1623// Set __parent to parent of null leaf
1624// Return reference to null leaf
1625// If __v exists, set parent to node of __v and return reference to node of __v
1890// If __v exists, return the parent of the node of __v and a reference to the pointer to the node of __v.
1891// If __v doesn't exist, return the parent of the null leaf and a reference to the pointer to the null leaf.
16261892template <class _Tp, class _Compare, class _Allocator>
16271893template <class _Key>
1628typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_equal(
1629 const_iterator __hint, __end_node_pointer& __parent, __node_base_pointer& __dummy, const _Key& __v) {
1630 if (__hint == end() || value_comp()(__v, *__hint)) // check before
1631 {
1894_LIBCPP_HIDE_FROM_ABI pair<typename __tree<_Tp, _Compare, _Allocator>::__end_node_pointer,
1895 typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&>
1896__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, __node_base_pointer& __dummy, const _Key& __v) {
1897 using _Pair = pair<__end_node_pointer, __node_base_pointer&>;
1898
1899 if (__hint == end() || value_comp()(__v, *__hint)) { // check before
16321900 // __v < *__hint
16331901 const_iterator __prior = __hint;
16341902 if (__prior == begin() || value_comp()(*--__prior, __v)) {
16351903 // *prev(__hint) < __v < *__hint
1636 if (__hint.__ptr_->__left_ == nullptr) {
1637 __parent = __hint.__ptr_;
1638 return __parent->__left_;
1639 } else {
1640 __parent = __prior.__ptr_;
1641 return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_;
1642 }
1904 if (__hint.__ptr_->__left_ == nullptr)
1905 return _Pair(__hint.__ptr_, __hint.__ptr_->__left_);
1906 return _Pair(__prior.__ptr_, static_cast<__node_pointer>(__prior.__ptr_)->__right_);
16431907 }
16441908 // __v <= *prev(__hint)
1645 return __find_equal(__parent, __v);
1646 } else if (value_comp()(*__hint, __v)) // check after
1647 {
1909 return __find_equal(__v);
1910 }
1911
1912 if (value_comp()(*__hint, __v)) { // check after
16481913 // *__hint < __v
16491914 const_iterator __next = std::next(__hint);
16501915 if (__next == end() || value_comp()(__v, *__next)) {
16511916 // *__hint < __v < *std::next(__hint)
1652 if (__hint.__get_np()->__right_ == nullptr) {
1653 __parent = __hint.__ptr_;
1654 return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_;
1655 } else {
1656 __parent = __next.__ptr_;
1657 return __parent->__left_;
1658 }
1917 if (__hint.__get_np()->__right_ == nullptr)
1918 return _Pair(__hint.__ptr_, static_cast<__node_pointer>(__hint.__ptr_)->__right_);
1919 return _Pair(__next.__ptr_, __next.__ptr_->__left_);
16591920 }
16601921 // *next(__hint) <= __v
1661 return __find_equal(__parent, __v);
1922 return __find_equal(__v);
16621923 }
1924
16631925 // else __v == *__hint
1664 __parent = __hint.__ptr_;
1665 __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
1666 return __dummy;
1926 __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
1927 return _Pair(__hint.__ptr_, __dummy);
16671928}
16681929
16691930template <class _Tp, class _Compare, class _Allocator>
......@@ -1674,46 +1935,10 @@ void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
16741935 __new_node->__parent_ = __parent;
16751936 // __new_node->__is_black_ is initialized in __tree_balance_after_insert
16761937 __child = __new_node;
1677 if (__begin_node()->__left_ != nullptr)
1678 __begin_node() = static_cast<__end_node_pointer>(__begin_node()->__left_);
1938 if (__begin_node_->__left_ != nullptr)
1939 __begin_node_ = static_cast<__end_node_pointer>(__begin_node_->__left_);
16791940 std::__tree_balance_after_insert(__end_node()->__left_, __child);
1680 ++size();
1681}
1682
1683template <class _Tp, class _Compare, class _Allocator>
1684template <class _Key, class... _Args>
1685pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1686__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) {
1687 __end_node_pointer __parent;
1688 __node_base_pointer& __child = __find_equal(__parent, __k);
1689 __node_pointer __r = static_cast<__node_pointer>(__child);
1690 bool __inserted = false;
1691 if (__child == nullptr) {
1692 __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
1693 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1694 __r = __h.release();
1695 __inserted = true;
1696 }
1697 return pair<iterator, bool>(iterator(__r), __inserted);
1698}
1699
1700template <class _Tp, class _Compare, class _Allocator>
1701template <class _Key, class... _Args>
1702pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1703__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
1704 const_iterator __p, _Key const& __k, _Args&&... __args) {
1705 __end_node_pointer __parent;
1706 __node_base_pointer __dummy;
1707 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k);
1708 __node_pointer __r = static_cast<__node_pointer>(__child);
1709 bool __inserted = false;
1710 if (__child == nullptr) {
1711 __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
1712 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1713 __r = __h.release();
1714 __inserted = true;
1715 }
1716 return pair<iterator, bool>(iterator(__r), __inserted);
1941 ++__size_;
17171942}
17181943
17191944template <class _Tp, class _Compare, class _Allocator>
......@@ -1722,51 +1947,18 @@ typename __tree<_Tp, _Compare, _Allocator>::__node_holder
17221947__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&&... __args) {
17231948 __node_allocator& __na = __node_alloc();
17241949 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1725 __node_traits::construct(__na, std::addressof(__h->__value_), std::forward<_Args>(__args)...);
1950 std::__construct_at(std::addressof(*__h), __na, std::forward<_Args>(__args)...);
17261951 __h.get_deleter().__value_constructed = true;
17271952 return __h;
17281953}
17291954
1730template <class _Tp, class _Compare, class _Allocator>
1731template <class... _Args>
1732pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1733__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) {
1734 __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
1735 __end_node_pointer __parent;
1736 __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
1737 __node_pointer __r = static_cast<__node_pointer>(__child);
1738 bool __inserted = false;
1739 if (__child == nullptr) {
1740 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1741 __r = __h.release();
1742 __inserted = true;
1743 }
1744 return pair<iterator, bool>(iterator(__r), __inserted);
1745}
1746
1747template <class _Tp, class _Compare, class _Allocator>
1748template <class... _Args>
1749typename __tree<_Tp, _Compare, _Allocator>::iterator
1750__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args) {
1751 __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
1752 __end_node_pointer __parent;
1753 __node_base_pointer __dummy;
1754 __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
1755 __node_pointer __r = static_cast<__node_pointer>(__child);
1756 if (__child == nullptr) {
1757 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1758 __r = __h.release();
1759 }
1760 return iterator(__r);
1761}
1762
17631955template <class _Tp, class _Compare, class _Allocator>
17641956template <class... _Args>
17651957typename __tree<_Tp, _Compare, _Allocator>::iterator
17661958__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) {
17671959 __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
17681960 __end_node_pointer __parent;
1769 __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
1961 __node_base_pointer& __child = __find_leaf_high(__parent, __h->__get_value());
17701962 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
17711963 return iterator(static_cast<__node_pointer>(__h.release()));
17721964}
......@@ -1777,53 +1969,19 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator
17771969__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, _Args&&... __args) {
17781970 __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
17791971 __end_node_pointer __parent;
1780 __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
1972 __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__get_value());
17811973 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
17821974 return iterator(static_cast<__node_pointer>(__h.release()));
17831975}
17841976
1785template <class _Tp, class _Compare, class _Allocator>
1786pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
1787__tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const value_type& __v, __node_pointer __nd) {
1788 __end_node_pointer __parent;
1789 __node_base_pointer& __child = __find_equal(__parent, __v);
1790 __node_pointer __r = static_cast<__node_pointer>(__child);
1791 bool __inserted = false;
1792 if (__child == nullptr) {
1793 __assign_value(__nd->__value_, __v);
1794 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
1795 __r = __nd;
1796 __inserted = true;
1797 }
1798 return pair<iterator, bool>(iterator(__r), __inserted);
1799}
1800
1801template <class _Tp, class _Compare, class _Allocator>
1802typename __tree<_Tp, _Compare, _Allocator>::iterator
1803__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) {
1804 __end_node_pointer __parent;
1805 __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_);
1806 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
1807 return iterator(__nd);
1808}
1809
1810template <class _Tp, class _Compare, class _Allocator>
1811typename __tree<_Tp, _Compare, _Allocator>::iterator
1812__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, __node_pointer __nd) {
1813 __end_node_pointer __parent;
1814 __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_);
1815 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
1816 return iterator(__nd);
1817}
1818
18191977template <class _Tp, class _Compare, class _Allocator>
18201978typename __tree<_Tp, _Compare, _Allocator>::iterator
18211979__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT {
18221980 iterator __r(__ptr);
18231981 ++__r;
1824 if (__begin_node() == __ptr)
1825 __begin_node() = __r.__ptr_;
1826 --size();
1982 if (__begin_node_ == __ptr)
1983 __begin_node_ = __r.__ptr_;
1984 --__size_;
18271985 std::__tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__ptr));
18281986 return __r;
18291987}
......@@ -1837,8 +1995,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(_NodeHandle&& __n
18371995 return _InsertReturnType{end(), false, _NodeHandle()};
18381996
18391997 __node_pointer __ptr = __nh.__ptr_;
1840 __end_node_pointer __parent;
1841 __node_base_pointer& __child = __find_equal(__parent, __ptr->__value_);
1998 auto [__parent, __child] = __find_equal(__ptr->__get_value());
18421999 if (__child != nullptr)
18432000 return _InsertReturnType{iterator(static_cast<__node_pointer>(__child)), false, std::move(__nh)};
18442001
......@@ -1855,10 +2012,9 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(const_iterator __
18552012 return end();
18562013
18572014 __node_pointer __ptr = __nh.__ptr_;
1858 __end_node_pointer __parent;
18592015 __node_base_pointer __dummy;
1860 __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy, __ptr->__value_);
1861 __node_pointer __r = static_cast<__node_pointer>(__child);
2016 auto [__parent, __child] = __find_equal(__hint, __dummy, __ptr->__get_value());
2017 __node_pointer __r = static_cast<__node_pointer>(__child);
18622018 if (__child == nullptr) {
18632019 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
18642020 __r = __ptr;
......@@ -1885,14 +2041,12 @@ _LIBCPP_HIDE_FROM_ABI _NodeHandle __tree<_Tp, _Compare, _Allocator>::__node_hand
18852041}
18862042
18872043template <class _Tp, class _Compare, class _Allocator>
1888template <class _Tree>
1889_LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source) {
1890 static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
1891
1892 for (typename _Tree::iterator __i = __source.begin(); __i != __source.end();) {
2044template <class _Comp2>
2045_LIBCPP_HIDE_FROM_ABI void
2046__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(__tree<_Tp, _Comp2, _Allocator>& __source) {
2047 for (iterator __i = __source.begin(); __i != __source.end();) {
18932048 __node_pointer __src_ptr = __i.__get_np();
1894 __end_node_pointer __parent;
1895 __node_base_pointer& __child = __find_equal(__parent, __src_ptr->__value_);
2049 auto [__parent, __child] = __find_equal(__src_ptr->__get_value());
18962050 ++__i;
18972051 if (__child != nullptr)
18982052 continue;
......@@ -1909,7 +2063,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh
19092063 return end();
19102064 __node_pointer __ptr = __nh.__ptr_;
19112065 __end_node_pointer __parent;
1912 __node_base_pointer& __child = __find_leaf_high(__parent, __ptr->__value_);
2066 __node_base_pointer& __child = __find_leaf_high(__parent, __ptr->__get_value());
19132067 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
19142068 __nh.__release_ptr();
19152069 return iterator(__ptr);
......@@ -1924,21 +2078,20 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(const_iterator __h
19242078
19252079 __node_pointer __ptr = __nh.__ptr_;
19262080 __end_node_pointer __parent;
1927 __node_base_pointer& __child = __find_leaf(__hint, __parent, __ptr->__value_);
2081 __node_base_pointer& __child = __find_leaf(__hint, __parent, __ptr->__get_value());
19282082 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
19292083 __nh.__release_ptr();
19302084 return iterator(__ptr);
19312085}
19322086
19332087template <class _Tp, class _Compare, class _Allocator>
1934template <class _Tree>
1935_LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source) {
1936 static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
1937
1938 for (typename _Tree::iterator __i = __source.begin(); __i != __source.end();) {
2088template <class _Comp2>
2089_LIBCPP_HIDE_FROM_ABI void
2090__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(__tree<_Tp, _Comp2, _Allocator>& __source) {
2091 for (iterator __i = __source.begin(); __i != __source.end();) {
19392092 __node_pointer __src_ptr = __i.__get_np();
19402093 __end_node_pointer __parent;
1941 __node_base_pointer& __child = __find_leaf_high(__parent, __src_ptr->__value_);
2094 __node_base_pointer& __child = __find_leaf_high(__parent, __src_ptr->__get_value());
19422095 ++__i;
19432096 __source.__remove_node_pointer(__src_ptr);
19442097 __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__src_ptr));
......@@ -1987,34 +2140,17 @@ __tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k) {
19872140 return __r;
19882141}
19892142
1990template <class _Tp, class _Compare, class _Allocator>
1991template <class _Key>
1992typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) {
1993 iterator __p = __lower_bound(__v, __root(), __end_node());
1994 if (__p != end() && !value_comp()(__v, *__p))
1995 return __p;
1996 return end();
1997}
1998
1999template <class _Tp, class _Compare, class _Allocator>
2000template <class _Key>
2001typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2002__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const {
2003 const_iterator __p = __lower_bound(__v, __root(), __end_node());
2004 if (__p != end() && !value_comp()(__v, *__p))
2005 return __p;
2006 return end();
2007}
2008
20092143template <class _Tp, class _Compare, class _Allocator>
20102144template <class _Key>
20112145typename __tree<_Tp, _Compare, _Allocator>::size_type
20122146__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const {
20132147 __node_pointer __rt = __root();
2148 auto __comp = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
20142149 while (__rt != nullptr) {
2015 if (value_comp()(__k, __rt->__value_)) {
2150 auto __comp_res = __comp(__k, __rt->__get_value());
2151 if (__comp_res.__less()) {
20162152 __rt = static_cast<__node_pointer>(__rt->__left_);
2017 } else if (value_comp()(__rt->__value_, __k))
2153 } else if (__comp_res.__greater())
20182154 __rt = static_cast<__node_pointer>(__rt->__right_);
20192155 else
20202156 return 1;
......@@ -2028,26 +2164,28 @@ typename __tree<_Tp, _Compare, _Allocator>::size_type
20282164__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const {
20292165 __end_node_pointer __result = __end_node();
20302166 __node_pointer __rt = __root();
2167 auto __comp = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
20312168 while (__rt != nullptr) {
2032 if (value_comp()(__k, __rt->__value_)) {
2169 auto __comp_res = __comp(__k, __rt->__get_value());
2170 if (__comp_res.__less()) {
20332171 __result = static_cast<__end_node_pointer>(__rt);
20342172 __rt = static_cast<__node_pointer>(__rt->__left_);
2035 } else if (value_comp()(__rt->__value_, __k))
2173 } else if (__comp_res.__greater())
20362174 __rt = static_cast<__node_pointer>(__rt->__right_);
20372175 else
20382176 return std::distance(
2039 __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
2040 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2177 __lower_bound_multi(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
2178 __upper_bound_multi(__k, static_cast<__node_pointer>(__rt->__right_), __result));
20412179 }
20422180 return 0;
20432181}
20442182
20452183template <class _Tp, class _Compare, class _Allocator>
20462184template <class _Key>
2047typename __tree<_Tp, _Compare, _Allocator>::iterator
2048__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
2185typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound_multi(
2186 const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
20492187 while (__root != nullptr) {
2050 if (!value_comp()(__root->__value_, __v)) {
2188 if (!value_comp()(__root->__get_value(), __v)) {
20512189 __result = static_cast<__end_node_pointer>(__root);
20522190 __root = static_cast<__node_pointer>(__root->__left_);
20532191 } else
......@@ -2058,10 +2196,10 @@ __tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, __node_pointer
20582196
20592197template <class _Tp, class _Compare, class _Allocator>
20602198template <class _Key>
2061typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound(
2199typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound_multi(
20622200 const _Key& __v, __node_pointer __root, __end_node_pointer __result) const {
20632201 while (__root != nullptr) {
2064 if (!value_comp()(__root->__value_, __v)) {
2202 if (!value_comp()(__root->__get_value(), __v)) {
20652203 __result = static_cast<__end_node_pointer>(__root);
20662204 __root = static_cast<__node_pointer>(__root->__left_);
20672205 } else
......@@ -2072,10 +2210,10 @@ typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare,
20722210
20732211template <class _Tp, class _Compare, class _Allocator>
20742212template <class _Key>
2075typename __tree<_Tp, _Compare, _Allocator>::iterator
2076__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
2213typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound_multi(
2214 const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
20772215 while (__root != nullptr) {
2078 if (value_comp()(__v, __root->__value_)) {
2216 if (value_comp()(__v, __root->__get_value())) {
20792217 __result = static_cast<__end_node_pointer>(__root);
20802218 __root = static_cast<__node_pointer>(__root->__left_);
20812219 } else
......@@ -2086,10 +2224,10 @@ __tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, __node_pointer
20862224
20872225template <class _Tp, class _Compare, class _Allocator>
20882226template <class _Key>
2089typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound(
2227typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound_multi(
20902228 const _Key& __v, __node_pointer __root, __end_node_pointer __result) const {
20912229 while (__root != nullptr) {
2092 if (value_comp()(__v, __root->__value_)) {
2230 if (value_comp()(__v, __root->__get_value())) {
20932231 __result = static_cast<__end_node_pointer>(__root);
20942232 __root = static_cast<__node_pointer>(__root->__left_);
20952233 } else
......@@ -2102,14 +2240,16 @@ template <class _Tp, class _Compare, class _Allocator>
21022240template <class _Key>
21032241pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator>
21042242__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) {
2105 typedef pair<iterator, iterator> _Pp;
2243 using _Pp = pair<iterator, iterator>;
21062244 __end_node_pointer __result = __end_node();
21072245 __node_pointer __rt = __root();
2246 auto __comp = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
21082247 while (__rt != nullptr) {
2109 if (value_comp()(__k, __rt->__value_)) {
2248 auto __comp_res = __comp(__k, __rt->__get_value());
2249 if (__comp_res.__less()) {
21102250 __result = static_cast<__end_node_pointer>(__rt);
21112251 __rt = static_cast<__node_pointer>(__rt->__left_);
2112 } else if (value_comp()(__rt->__value_, __k))
2252 } else if (__comp_res.__greater())
21132253 __rt = static_cast<__node_pointer>(__rt->__right_);
21142254 else
21152255 return _Pp(iterator(__rt),
......@@ -2124,14 +2264,16 @@ template <class _Key>
21242264pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
21252265 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
21262266__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const {
2127 typedef pair<const_iterator, const_iterator> _Pp;
2267 using _Pp = pair<const_iterator, const_iterator>;
21282268 __end_node_pointer __result = __end_node();
21292269 __node_pointer __rt = __root();
2270 auto __comp = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
21302271 while (__rt != nullptr) {
2131 if (value_comp()(__k, __rt->__value_)) {
2272 auto __comp_res = __comp(__k, __rt->__get_value());
2273 if (__comp_res.__less()) {
21322274 __result = static_cast<__end_node_pointer>(__rt);
21332275 __rt = static_cast<__node_pointer>(__rt->__left_);
2134 } else if (value_comp()(__rt->__value_, __k))
2276 } else if (__comp_res.__greater())
21352277 __rt = static_cast<__node_pointer>(__rt->__right_);
21362278 else
21372279 return _Pp(
......@@ -2146,18 +2288,21 @@ template <class _Tp, class _Compare, class _Allocator>
21462288template <class _Key>
21472289pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator>
21482290__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) {
2149 typedef pair<iterator, iterator> _Pp;
2291 using _Pp = pair<iterator, iterator>;
21502292 __end_node_pointer __result = __end_node();
2151 __node_pointer __rt = __root();
2293 __node_pointer __rt = __root();
2294 auto __comp = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
21522295 while (__rt != nullptr) {
2153 if (value_comp()(__k, __rt->__value_)) {
2296 auto __comp_res = __comp(__k, __rt->__get_value());
2297 if (__comp_res.__less()) {
21542298 __result = static_cast<__end_node_pointer>(__rt);
21552299 __rt = static_cast<__node_pointer>(__rt->__left_);
2156 } else if (value_comp()(__rt->__value_, __k))
2300 } else if (__comp_res.__greater())
21572301 __rt = static_cast<__node_pointer>(__rt->__right_);
21582302 else
2159 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
2160 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2303 return _Pp(
2304 __lower_bound_multi(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
2305 __upper_bound_multi(__k, static_cast<__node_pointer>(__rt->__right_), __result));
21612306 }
21622307 return _Pp(iterator(__result), iterator(__result));
21632308}
......@@ -2167,18 +2312,21 @@ template <class _Key>
21672312pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
21682313 typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
21692314__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const {
2170 typedef pair<const_iterator, const_iterator> _Pp;
2315 using _Pp = pair<const_iterator, const_iterator>;
21712316 __end_node_pointer __result = __end_node();
2172 __node_pointer __rt = __root();
2317 __node_pointer __rt = __root();
2318 auto __comp = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
21732319 while (__rt != nullptr) {
2174 if (value_comp()(__k, __rt->__value_)) {
2320 auto __comp_res = __comp(__k, __rt->__get_value());
2321 if (__comp_res.__less()) {
21752322 __result = static_cast<__end_node_pointer>(__rt);
21762323 __rt = static_cast<__node_pointer>(__rt->__left_);
2177 } else if (value_comp()(__rt->__value_, __k))
2324 } else if (__comp_res.__greater())
21782325 __rt = static_cast<__node_pointer>(__rt->__right_);
21792326 else
2180 return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
2181 __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
2327 return _Pp(
2328 __lower_bound_multi(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
2329 __upper_bound_multi(__k, static_cast<__node_pointer>(__rt->__right_), __result));
21822330 }
21832331 return _Pp(const_iterator(__result), const_iterator(__result));
21842332}
......@@ -2187,13 +2335,13 @@ template <class _Tp, class _Compare, class _Allocator>
21872335typename __tree<_Tp, _Compare, _Allocator>::__node_holder
21882336__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT {
21892337 __node_pointer __np = __p.__get_np();
2190 if (__begin_node() == __p.__ptr_) {
2338 if (__begin_node_ == __p.__ptr_) {
21912339 if (__np->__right_ != nullptr)
2192 __begin_node() = static_cast<__end_node_pointer>(__np->__right_);
2340 __begin_node_ = static_cast<__end_node_pointer>(__np->__right_);
21932341 else
2194 __begin_node() = static_cast<__end_node_pointer>(__np->__parent_);
2342 __begin_node_ = static_cast<__end_node_pointer>(__np->__parent_);
21952343 }
2196 --size();
2344 --__size_;
21972345 std::__tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__np));
21982346 return __node_holder(__np, _Dp(__node_alloc(), true));
21992347}
lib/libcxx/include/__tuple/sfinae_helpers.h+1-44
......@@ -10,20 +10,6 @@
1010#define _LIBCPP___TUPLE_SFINAE_HELPERS_H
1111
1212#include <__config>
13#include <__cstddef/size_t.h>
14#include <__fwd/tuple.h>
15#include <__tuple/make_tuple_types.h>
16#include <__tuple/tuple_element.h>
17#include <__tuple/tuple_like_ext.h>
18#include <__tuple/tuple_size.h>
19#include <__tuple/tuple_types.h>
20#include <__type_traits/conjunction.h>
21#include <__type_traits/enable_if.h>
22#include <__type_traits/integral_constant.h>
23#include <__type_traits/is_constructible.h>
24#include <__type_traits/is_same.h>
25#include <__type_traits/remove_cvref.h>
26#include <__type_traits/remove_reference.h>
2713
2814#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2915# pragma GCC system_header
......@@ -33,36 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3319
3420#ifndef _LIBCPP_CXX03_LANG
3521
36struct __tuple_sfinae_base {
37 template <template <class, class...> class _Trait, class... _LArgs, class... _RArgs>
38 static auto __do_test(__tuple_types<_LArgs...>,
39 __tuple_types<_RArgs...>) -> __all<__enable_if_t<_Trait<_LArgs, _RArgs>::value, bool>{true}...>;
40 template <template <class...> class>
41 static auto __do_test(...) -> false_type;
42
43 template <class _FromArgs, class _ToArgs>
44 using __constructible _LIBCPP_NODEBUG = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{}));
45};
46
47// __tuple_constructible
48
49template <class _Tp,
50 class _Up,
51 bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
52 bool = __tuple_like_ext<_Up>::value>
53struct __tuple_constructible : public false_type {};
54
55template <class _Tp, class _Up>
56struct __tuple_constructible<_Tp, _Up, true, true>
57 : public __tuple_sfinae_base::__constructible< typename __make_tuple_types<_Tp>::type,
58 typename __make_tuple_types<_Up>::type > {};
59
60template <size_t _Ip, class... _Tp>
61struct tuple_element<_Ip, tuple<_Tp...> > {
62 using type _LIBCPP_NODEBUG = typename tuple_element<_Ip, __tuple_types<_Tp...> >::type;
63};
64
65struct _LIBCPP_EXPORTED_FROM_ABI __check_tuple_constructor_fail {
22struct __check_tuple_constructor_fail {
6623 static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() { return false; }
6724 static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() { return false; }
6825 template <class...>
lib/libcxx/include/__tuple/tuple_element.h-12
......@@ -11,8 +11,6 @@
1111
1212#include <__config>
1313#include <__cstddef/size_t.h>
14#include <__tuple/tuple_indices.h>
15#include <__tuple/tuple_types.h>
1614
1715#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1816# pragma GCC system_header
......@@ -38,21 +36,11 @@ struct tuple_element<_Ip, const volatile _Tp> {
3836 using type _LIBCPP_NODEBUG = const volatile typename tuple_element<_Ip, _Tp>::type;
3937};
4038
41#ifndef _LIBCPP_CXX03_LANG
42
43template <size_t _Ip, class... _Types>
44struct tuple_element<_Ip, __tuple_types<_Types...> > {
45 static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range");
46 using type _LIBCPP_NODEBUG = __type_pack_element<_Ip, _Types...>;
47};
48
4939# if _LIBCPP_STD_VER >= 14
5040template <size_t _Ip, class... _Tp>
5141using tuple_element_t _LIBCPP_NODEBUG = typename tuple_element<_Ip, _Tp...>::type;
5242# endif
5343
54#endif // _LIBCPP_CXX03_LANG
55
5644_LIBCPP_END_NAMESPACE_STD
5745
5846#endif // _LIBCPP___TUPLE_TUPLE_ELEMENT_H
lib/libcxx/include/__tuple/tuple_size.h-4
......@@ -12,7 +12,6 @@
1212#include <__config>
1313#include <__cstddef/size_t.h>
1414#include <__fwd/tuple.h>
15#include <__tuple/tuple_types.h>
1615#include <__type_traits/enable_if.h>
1716#include <__type_traits/integral_constant.h>
1817#include <__type_traits/is_const.h>
......@@ -59,9 +58,6 @@ struct tuple_size<const volatile _Tp> : public tuple_size<_Tp> {};
5958template <class... _Tp>
6059struct tuple_size<tuple<_Tp...> > : public integral_constant<size_t, sizeof...(_Tp)> {};
6160
62template <class... _Tp>
63struct tuple_size<__tuple_types<_Tp...> > : public integral_constant<size_t, sizeof...(_Tp)> {};
64
6561# if _LIBCPP_STD_VER >= 17
6662template <class _Tp>
6763inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
lib/libcxx/include/__tuple/tuple_transform.h created+45
......@@ -0,0 +1,45 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___TUPLE_TUPLE_TRANSFORM_H
11#define _LIBCPP___TUPLE_TUPLE_TRANSFORM_H
12
13#include <__config>
14
15#include <__functional/invoke.h>
16#include <__utility/forward.h>
17#include <tuple>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23_LIBCPP_PUSH_MACROS
24#include <__undef_macros>
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28#if _LIBCPP_STD_VER >= 23
29
30template <class _Fun, class _Tuple>
31_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_transform(_Fun&& __f, _Tuple&& __tuple) {
32 return std::apply(
33 [&]<class... _Types>(_Types&&... __elements) {
34 return tuple<invoke_result_t<_Fun&, _Types>...>(std::invoke(__f, std::forward<_Types>(__elements))...);
35 },
36 std::forward<_Tuple>(__tuple));
37}
38
39#endif // _LIBCPP_STD_VER >= 23
40
41_LIBCPP_END_NAMESPACE_STD
42
43_LIBCPP_POP_MACROS
44
45#endif // _LIBCPP___TUPLE_TUPLE_TRANSFORM_H
lib/libcxx/include/__type_traits/aligned_storage.h+13-40
......@@ -11,8 +11,6 @@
1111
1212#include <__config>
1313#include <__cstddef/size_t.h>
14#include <__type_traits/integral_constant.h>
15#include <__type_traits/type_list.h>
1614
1715#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1816# pragma GCC system_header
......@@ -21,10 +19,10 @@
2119_LIBCPP_BEGIN_NAMESPACE_STD
2220
2321template <class _Tp>
24struct __align_type {
25 static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp);
26 typedef _Tp type;
27};
22struct _ALIGNAS(_LIBCPP_PREFERRED_ALIGNOF(_Tp)) _AlignedAsT {};
23
24template <class... _Args>
25struct __max_align_impl : _AlignedAsT<_Args>... {};
2826
2927struct __struct_double {
3028 long double __lx;
......@@ -33,41 +31,16 @@ struct __struct_double4 {
3331 double __lx[4];
3432};
3533
36using __all_types _LIBCPP_NODEBUG =
37 __type_list<__align_type<unsigned char>,
38 __align_type<unsigned short>,
39 __align_type<unsigned int>,
40 __align_type<unsigned long>,
41 __align_type<unsigned long long>,
42 __align_type<double>,
43 __align_type<long double>,
44 __align_type<__struct_double>,
45 __align_type<__struct_double4>,
46 __align_type<int*> >;
47
48template <class _TL, size_t _Len>
49struct __find_max_align;
50
51template <class _Head, size_t _Len>
52struct __find_max_align<__type_list<_Head>, _Len> : public integral_constant<size_t, _Head::value> {};
53
54template <size_t _Len, size_t _A1, size_t _A2>
55struct __select_align {
56private:
57 static const size_t __min = _A2 < _A1 ? _A2 : _A1;
58 static const size_t __max = _A1 < _A2 ? _A2 : _A1;
59
60public:
61 static const size_t value = _Len < __max ? __min : __max;
62};
34inline const size_t __aligned_storage_max_align =
35 _LIBCPP_ALIGNOF(__max_align_impl<unsigned long long, double, long double, __struct_double, __struct_double4, int*>);
6336
64template <class _Head, class... _Tail, size_t _Len>
65struct __find_max_align<__type_list<_Head, _Tail...>, _Len>
66 : public integral_constant<
67 size_t,
68 __select_align<_Len, _Head::value, __find_max_align<__type_list<_Tail...>, _Len>::value>::value> {};
37template <size_t _Len>
38inline const size_t __aligned_storage_alignment =
39 _Len > __aligned_storage_max_align
40 ? __aligned_storage_max_align
41 : size_t(1) << ((sizeof(size_t) * __CHAR_BIT__) - __builtin_clzg(_Len) - 1);
6942
70template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
43template <size_t _Len, size_t _Align = __aligned_storage_alignment<_Len> >
7144struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_NO_SPECIALIZATIONS aligned_storage {
7245 union _ALIGNAS(_Align) type {
7346 unsigned char __data[(_Len + _Align - 1) / _Align * _Align];
......@@ -77,7 +50,7 @@ struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_NO_SPECIALIZATIONS aligned_storage {
7750#if _LIBCPP_STD_VER >= 14
7851
7952_LIBCPP_SUPPRESS_DEPRECATED_PUSH
80template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
53template <size_t _Len, size_t _Align = __aligned_storage_alignment<_Len> >
8154using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type;
8255_LIBCPP_SUPPRESS_DEPRECATED_POP
8356
lib/libcxx/include/__type_traits/desugars_to.h+4
......@@ -10,6 +10,7 @@
1010#define _LIBCPP___TYPE_TRAITS_DESUGARS_TO_H
1111
1212#include <__config>
13#include <__type_traits/integral_constant.h>
1314
1415#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1516# pragma GCC system_header
......@@ -64,6 +65,9 @@ template <class _CanonicalTag, class _Operation, class... _Args>
6465inline const bool __desugars_to_v<_CanonicalTag, _Operation&&, _Args...> =
6566 __desugars_to_v<_CanonicalTag, _Operation, _Args...>;
6667
68template <class _CanonicalTag, class _Operation, class... _Args>
69struct __desugars_to : integral_constant<bool, __desugars_to_v<_CanonicalTag, _Operation, _Args...> > {};
70
6771_LIBCPP_END_NAMESPACE_STD
6872
6973#endif // _LIBCPP___TYPE_TRAITS_DESUGARS_TO_H
lib/libcxx/include/__type_traits/invoke.h+8
......@@ -62,6 +62,9 @@
6262//
6363// template <class Func, class... Args>
6464// using __invoke_result_t = invoke_result_t<Func, Args...>;
65//
66// template <class Ret, class Func, class... Args>
67// struct __is_invocable_r : is_invocable_r<Ret, Func, Args...> {};
6568
6669_LIBCPP_BEGIN_NAMESPACE_STD
6770
......@@ -112,8 +115,10 @@ inline const bool __is_invocable_r_v = __is_invocable_r_impl<_Ret, __is_invocabl
112115template <bool __is_invocable, class... _Args>
113116inline const bool __is_nothrow_invocable_impl = false;
114117
118# ifndef _LIBCPP_CXX03_LANG
115119template <class... _Args>
116120inline const bool __is_nothrow_invocable_impl<true, _Args...> = noexcept(__builtin_invoke(std::declval<_Args>()...));
121# endif
117122
118123template <class... _Args>
119124inline const bool __is_nothrow_invocable_v = __is_nothrow_invocable_impl<__is_invocable_v<_Args...>, _Args...>;
......@@ -327,6 +332,9 @@ using __invoke_result_t _LIBCPP_NODEBUG = typename __invoke_result<_Func, _Args.
327332
328333#endif // __has_builtin(__builtin_invoke_r)
329334
335template <class _Ret, class _Func, class... _Args>
336struct __is_invocable_r : integral_constant<bool, __is_invocable_r_v<_Ret, _Func, _Args...> > {};
337
330338template <class _Ret, bool = is_void<_Ret>::value>
331339struct __invoke_void_return_wrapper {
332340 template <class... _Args>
lib/libcxx/include/__type_traits/is_allocator.h+6-7
......@@ -11,7 +11,6 @@
1111
1212#include <__config>
1313#include <__cstddef/size_t.h>
14#include <__type_traits/integral_constant.h>
1514#include <__type_traits/void_t.h>
1615#include <__utility/declval.h>
1716
......@@ -21,13 +20,13 @@
2120
2221_LIBCPP_BEGIN_NAMESPACE_STD
2322
24template <typename _Alloc, typename = void, typename = void>
25struct __is_allocator : false_type {};
23template <class _Alloc, class = void, class = void>
24inline const bool __is_allocator_v = false;
2625
27template <typename _Alloc>
28struct __is_allocator<_Alloc,
29 __void_t<typename _Alloc::value_type>,
30 __void_t<decltype(std::declval<_Alloc&>().allocate(size_t(0)))> > : true_type {};
26template <class _Alloc>
27inline const bool __is_allocator_v<_Alloc,
28 __void_t<typename _Alloc::value_type>,
29 __void_t<decltype(std::declval<_Alloc&>().allocate(size_t()))> > = true;
3130
3231_LIBCPP_END_NAMESPACE_STD
3332
lib/libcxx/include/__type_traits/is_array.h+26
......@@ -26,6 +26,32 @@ template <class _Tp>
2626_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_array_v = __is_array(_Tp);
2727#endif
2828
29template <class _Tp>
30inline const bool __is_bounded_array_v = __is_bounded_array(_Tp);
31
32#if _LIBCPP_STD_VER >= 20
33
34template <class _Tp>
35struct _LIBCPP_NO_SPECIALIZATIONS is_bounded_array : bool_constant<__is_bounded_array(_Tp)> {};
36
37template <class _Tp>
38_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp);
39
40#endif
41
42template <class _Tp>
43inline const bool __is_unbounded_array_v = __is_unbounded_array(_Tp);
44
45#if _LIBCPP_STD_VER >= 20
46
47template <class _Tp>
48struct _LIBCPP_NO_SPECIALIZATIONS is_unbounded_array : bool_constant<__is_unbounded_array(_Tp)> {};
49
50template <class _Tp>
51_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_unbounded_array_v = __is_unbounded_array(_Tp);
52
53#endif
54
2955_LIBCPP_END_NAMESPACE_STD
3056
3157#endif // _LIBCPP___TYPE_TRAITS_IS_ARRAY_H
lib/libcxx/include/__type_traits/is_equality_comparable.h+16-21
......@@ -27,11 +27,11 @@
2727_LIBCPP_BEGIN_NAMESPACE_STD
2828
2929template <class _Tp, class _Up, class = void>
30struct __is_equality_comparable : false_type {};
30inline const bool __is_equality_comparable_v = false;
3131
3232template <class _Tp, class _Up>
33struct __is_equality_comparable<_Tp, _Up, __void_t<decltype(std::declval<_Tp>() == std::declval<_Up>())> > : true_type {
34};
33inline const bool
34 __is_equality_comparable_v<_Tp, _Up, __void_t<decltype(std::declval<_Tp>() == std::declval<_Up>())> > = true;
3535
3636// A type is_trivially_equality_comparable if the expression `a == b` is equivalent to `std::memcmp(&a, &b, sizeof(T))`
3737// (with `a` and `b` being of type `T`). For the case where we compare two object of the same type, we can use
......@@ -48,40 +48,35 @@ struct __is_equality_comparable<_Tp, _Up, __void_t<decltype(std::declval<_Tp>()
4848// representation may not be equivalent.
4949
5050template <class _Tp, class _Up, class = void>
51struct __libcpp_is_trivially_equality_comparable_impl : false_type {};
51inline const bool __is_trivially_equality_comparable_impl = false;
5252
5353template <class _Tp>
54struct __libcpp_is_trivially_equality_comparable_impl<_Tp, _Tp>
54inline const bool __is_trivially_equality_comparable_impl<_Tp, _Tp>
5555#if __has_builtin(__is_trivially_equality_comparable)
56 : integral_constant<bool, __is_trivially_equality_comparable(_Tp) && __is_equality_comparable<_Tp, _Tp>::value> {
57};
56 = __is_trivially_equality_comparable(_Tp) && __is_equality_comparable_v<_Tp, _Tp>;
5857#else
59 : is_integral<_Tp> {
60};
58 = is_integral<_Tp>::value;
6159#endif // __has_builtin(__is_trivially_equality_comparable)
6260
6361template <class _Tp, class _Up>
64struct __libcpp_is_trivially_equality_comparable_impl<
62inline const bool __is_trivially_equality_comparable_impl<
6563 _Tp,
6664 _Up,
67 __enable_if_t<is_integral<_Tp>::value && is_integral<_Up>::value && !is_same<_Tp, _Up>::value &&
68 is_signed<_Tp>::value == is_signed<_Up>::value && sizeof(_Tp) == sizeof(_Up)> > : true_type {};
65 __enable_if_t<is_integral<_Tp>::value && is_integral<_Up>::value && !is_same<_Tp, _Up>::value> > =
66 is_signed<_Tp>::value == is_signed<_Up>::value && sizeof(_Tp) == sizeof(_Up);
6967
7068template <class _Tp>
71struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Tp*> : true_type {};
69inline const bool __is_trivially_equality_comparable_impl<_Tp*, _Tp*> = true;
7270
7371// TODO: Use is_pointer_inverconvertible_base_of
7472template <class _Tp, class _Up>
75struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Up*>
76 : integral_constant<
77 bool,
78 __is_equality_comparable<_Tp*, _Up*>::value &&
79 (is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value || is_void<_Tp>::value || is_void<_Up>::value)> {
80};
73inline const bool __is_trivially_equality_comparable_impl<_Tp*, _Up*> =
74 __is_equality_comparable_v<_Tp*, _Up*> &&
75 (is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value || is_void<_Tp>::value || is_void<_Up>::value);
8176
8277template <class _Tp, class _Up>
83using __libcpp_is_trivially_equality_comparable _LIBCPP_NODEBUG =
84 __libcpp_is_trivially_equality_comparable_impl<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >;
78inline const bool __is_trivially_equality_comparable_v =
79 __is_trivially_equality_comparable_impl<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >;
8580
8681_LIBCPP_END_NAMESPACE_STD
8782
lib/libcxx/include/__type_traits/is_final.h+1-1
......@@ -19,7 +19,7 @@
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
2121template <class _Tp>
22struct __libcpp_is_final : integral_constant<bool, __is_final(_Tp)> {};
22inline const bool __is_final_v = __is_final(_Tp);
2323
2424#if _LIBCPP_STD_VER >= 14
2525template <class _Tp>
lib/libcxx/include/__type_traits/is_floating_point.h+7-6
......@@ -20,18 +20,19 @@
2020_LIBCPP_BEGIN_NAMESPACE_STD
2121
2222// clang-format off
23template <class _Tp> struct __libcpp_is_floating_point : false_type {};
24template <> struct __libcpp_is_floating_point<float> : true_type {};
25template <> struct __libcpp_is_floating_point<double> : true_type {};
26template <> struct __libcpp_is_floating_point<long double> : true_type {};
23template <class _Tp> inline const bool __is_floating_point_impl = false;
24template <> inline const bool __is_floating_point_impl<float> = true;
25template <> inline const bool __is_floating_point_impl<double> = true;
26template <> inline const bool __is_floating_point_impl<long double> = true;
2727// clang-format on
2828
2929template <class _Tp>
30struct _LIBCPP_NO_SPECIALIZATIONS is_floating_point : __libcpp_is_floating_point<__remove_cv_t<_Tp> > {};
30struct _LIBCPP_NO_SPECIALIZATIONS is_floating_point
31 : integral_constant<bool, __is_floating_point_impl<__remove_cv_t<_Tp> > > {};
3132
3233#if _LIBCPP_STD_VER >= 17
3334template <class _Tp>
34_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
35_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_floating_point_v = __is_floating_point_impl<__remove_cv_t<_Tp>>;
3536#endif
3637
3738_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/__type_traits/is_generic_transparent_comparator.h created+30
......@@ -0,0 +1,30 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TYPE_TRAITS_IS_GENERIC_TRANSPARENT_COMPARATOR_H
10#define _LIBCPP___TYPE_TRAITS_IS_GENERIC_TRANSPARENT_COMPARATOR_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15# pragma GCC system_header
16#endif
17
18_LIBCPP_BEGIN_NAMESPACE_STD
19
20// This trait returns true if the given _Comparator is known to accept any two types for comparison. This is separate
21// from `__is_transparent_v`, since that only enables overloads of specific functions, but doesn't give any semantic
22// guarantees. This trait guarantess that the comparator simply calls the appropriate comparison functions for any two
23// types.
24
25template <class _Comparator>
26inline const bool __is_generic_transparent_comparator_v = false;
27
28_LIBCPP_END_NAMESPACE_STD
29
30#endif // _LIBCPP___TYPE_TRAITS_IS_GENERIC_TRANSPARENT_COMPARATOR_H
lib/libcxx/include/__type_traits/is_specialization.h+2-6
......@@ -30,15 +30,11 @@
3030
3131_LIBCPP_BEGIN_NAMESPACE_STD
3232
33#if _LIBCPP_STD_VER >= 17
34
3533template <class _Tp, template <class...> class _Template>
36inline constexpr bool __is_specialization_v = false; // true if and only if _Tp is a specialization of _Template
34inline const bool __is_specialization_v = false; // true if and only if _Tp is a specialization of _Template
3735
3836template <template <class...> class _Template, class... _Args>
39inline constexpr bool __is_specialization_v<_Template<_Args...>, _Template> = true;
40
41#endif // _LIBCPP_STD_VER >= 17
37inline const bool __is_specialization_v<_Template<_Args...>, _Template> = true;
4238
4339_LIBCPP_END_NAMESPACE_STD
4440
lib/libcxx/include/__type_traits/is_within_lifetime.h created+29
......@@ -0,0 +1,29 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TYPE_TRAITS_IS_WITHIN_LIFETIME_H
10#define _LIBCPP___TYPE_TRAITS_IS_WITHIN_LIFETIME_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15# pragma GCC system_header
16#endif
17
18_LIBCPP_BEGIN_NAMESPACE_STD
19
20#if _LIBCPP_STD_VER >= 26 && __has_builtin(__builtin_is_within_lifetime)
21template <class _Tp>
22_LIBCPP_HIDE_FROM_ABI consteval bool is_within_lifetime(const _Tp* __p) noexcept {
23 return __builtin_is_within_lifetime(__p);
24}
25#endif
26
27_LIBCPP_END_NAMESPACE_STD
28
29#endif // _LIBCPP___TYPE_TRAITS_IS_WITHIN_LIFETIME_H
lib/libcxx/include/__type_traits/make_transparent.h created+52
......@@ -0,0 +1,52 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TYPE_TRAITS_MAKE_TRANSPARENT_H
10#define _LIBCPP___TYPE_TRAITS_MAKE_TRANSPARENT_H
11
12#include <__config>
13#include <__type_traits/enable_if.h>
14#include <__type_traits/is_empty.h>
15#include <__type_traits/is_same.h>
16
17#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18# pragma GCC system_header
19#endif
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23// __make_transparent tries to create a transparent comparator from its non-transparent counterpart, e.g. obtain
24// `less<>` from `less<T>`. This is useful in cases where conversions can be avoided (e.g. a string literal to a
25// std::string).
26
27template <class _Tp, class _Comparator>
28struct __make_transparent {
29 using type _LIBCPP_NODEBUG = _Comparator;
30};
31
32template <class _Tp, class _Comparator>
33using __make_transparent_t _LIBCPP_NODEBUG = typename __make_transparent<_Tp, _Comparator>::type;
34
35template <class _Tp,
36 class _Comparator,
37 __enable_if_t<is_same<_Comparator, __make_transparent_t<_Tp, _Comparator> >::value, int> = 0>
38_LIBCPP_HIDE_FROM_ABI _Comparator& __as_transparent(_Comparator& __comp) {
39 return __comp;
40}
41
42template <class _Tp,
43 class _Comparator,
44 __enable_if_t<!is_same<_Comparator, __make_transparent_t<_Tp, _Comparator> >::value, int> = 0>
45_LIBCPP_HIDE_FROM_ABI __make_transparent_t<_Tp, _Comparator> __as_transparent(_Comparator&) {
46 static_assert(is_empty<_Comparator>::value);
47 return __make_transparent_t<_Tp, _Comparator>();
48}
49
50_LIBCPP_END_NAMESPACE_STD
51
52#endif // _LIBCPP___TYPE_TRAITS_MAKE_TRANSPARENT_H
lib/libcxx/include/__type_traits/reference_constructs_from_temporary.h+1-7
......@@ -18,7 +18,7 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21#if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_constructs_from_temporary)
21#if _LIBCPP_STD_VER >= 23
2222
2323template <class _Tp, class _Up>
2424struct _LIBCPP_NO_SPECIALIZATIONS reference_constructs_from_temporary
......@@ -30,14 +30,8 @@ _LIBCPP_NO_SPECIALIZATIONS inline constexpr bool reference_constructs_from_tempo
3030
3131#endif
3232
33#if __has_builtin(__reference_constructs_from_temporary)
3433template <class _Tp, class _Up>
3534inline const bool __reference_constructs_from_temporary_v = __reference_constructs_from_temporary(_Tp, _Up);
36#else
37// TODO(LLVM 22): Remove this as all supported compilers should have __reference_constructs_from_temporary implemented.
38template <class _Tp, class _Up>
39inline const bool __reference_constructs_from_temporary_v = __reference_binds_to_temporary(_Tp, _Up);
40#endif
4135
4236_LIBCPP_END_NAMESPACE_STD
4337
lib/libcxx/include/__type_traits/reference_converts_from_temporary.h+1-1
......@@ -18,7 +18,7 @@
1818
1919_LIBCPP_BEGIN_NAMESPACE_STD
2020
21#if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_converts_from_temporary)
21#if _LIBCPP_STD_VER >= 23
2222
2323template <class _Tp, class _Up>
2424struct _LIBCPP_NO_SPECIALIZATIONS reference_converts_from_temporary
lib/libcxx/include/__utility/cmp.h+19-7
......@@ -26,10 +26,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2626
2727#if _LIBCPP_STD_VER >= 20
2828
29template <typename _Tp, typename _Ip>
30concept __comparison_can_promote_to =
31 sizeof(_Tp) < sizeof(_Ip) || (sizeof(_Tp) == sizeof(_Ip) && __signed_integer<_Tp>);
32
2933template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
30_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
34[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
3135 if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
3236 return __t == __u;
37 else if constexpr (__comparison_can_promote_to<_Tp, int> && __comparison_can_promote_to<_Up, int>)
38 return static_cast<int>(__t) == static_cast<int>(__u);
39 else if constexpr (__comparison_can_promote_to<_Tp, long long> && __comparison_can_promote_to<_Up, long long>)
40 return static_cast<long long>(__t) == static_cast<long long>(__u);
3341 else if constexpr (is_signed_v<_Tp>)
3442 return __t < 0 ? false : make_unsigned_t<_Tp>(__t) == __u;
3543 else
......@@ -37,14 +45,18 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
3745}
3846
3947template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
40_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept {
48[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept {
4149 return !std::cmp_equal(__t, __u);
4250}
4351
4452template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
45_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept {
53[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept {
4654 if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
4755 return __t < __u;
56 else if constexpr (__comparison_can_promote_to<_Tp, int> && __comparison_can_promote_to<_Up, int>)
57 return static_cast<int>(__t) < static_cast<int>(__u);
58 else if constexpr (__comparison_can_promote_to<_Tp, long long> && __comparison_can_promote_to<_Up, long long>)
59 return static_cast<long long>(__t) < static_cast<long long>(__u);
4860 else if constexpr (is_signed_v<_Tp>)
4961 return __t < 0 ? true : make_unsigned_t<_Tp>(__t) < __u;
5062 else
......@@ -52,22 +64,22 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept {
5264}
5365
5466template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
55_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater(_Tp __t, _Up __u) noexcept {
67[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater(_Tp __t, _Up __u) noexcept {
5668 return std::cmp_less(__u, __t);
5769}
5870
5971template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
60_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less_equal(_Tp __t, _Up __u) noexcept {
72[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less_equal(_Tp __t, _Up __u) noexcept {
6173 return !std::cmp_greater(__t, __u);
6274}
6375
6476template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
65_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater_equal(_Tp __t, _Up __u) noexcept {
77[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater_equal(_Tp __t, _Up __u) noexcept {
6678 return !std::cmp_less(__t, __u);
6779}
6880
6981template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
70_LIBCPP_HIDE_FROM_ABI constexpr bool in_range(_Up __u) noexcept {
82[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool in_range(_Up __u) noexcept {
7183 return std::cmp_less_equal(__u, numeric_limits<_Tp>::max()) &&
7284 std::cmp_greater_equal(__u, numeric_limits<_Tp>::min());
7385}
lib/libcxx/include/__utility/default_three_way_comparator.h created+70
......@@ -0,0 +1,70 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_DEFAULT_THREE_WAY_COMPARATOR_H
10#define _LIBCPP___UTILITY_DEFAULT_THREE_WAY_COMPARATOR_H
11
12#include <__config>
13#include <__type_traits/enable_if.h>
14#include <__type_traits/is_arithmetic.h>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17# pragma GCC system_header
18#endif
19
20_LIBCPP_BEGIN_NAMESPACE_STD
21
22// This struct can be specialized to provide a three way comparator between _LHS and _RHS.
23// The return value should be
24// - less than zero if (lhs_val < rhs_val)
25// - greater than zero if (rhs_val < lhs_val)
26// - zero otherwise
27template <class _LHS, class _RHS, class = void>
28struct __default_three_way_comparator;
29
30template <class _LHS, class _RHS>
31struct __default_three_way_comparator<_LHS,
32 _RHS,
33 __enable_if_t<is_arithmetic<_LHS>::value && is_arithmetic<_RHS>::value> > {
34 _LIBCPP_HIDE_FROM_ABI static int operator()(_LHS __lhs, _RHS __rhs) {
35 if (__lhs < __rhs)
36 return -1;
37 if (__lhs > __rhs)
38 return 1;
39 return 0;
40 }
41};
42
43#if _LIBCPP_STD_VER >= 20 && __has_builtin(__builtin_lt_synthesizes_from_spaceship)
44template <class _LHS, class _RHS>
45struct __default_three_way_comparator<
46 _LHS,
47 _RHS,
48 __enable_if_t<!(is_arithmetic<_LHS>::value && is_arithmetic<_RHS>::value) &&
49 __builtin_lt_synthesizes_from_spaceship(const _LHS&, const _RHS&)>> {
50 _LIBCPP_HIDE_FROM_ABI static int operator()(const _LHS& __lhs, const _RHS& __rhs) {
51 auto __res = __lhs <=> __rhs;
52 if (__res < 0)
53 return -1;
54 if (__res > 0)
55 return 1;
56 return 0;
57 }
58};
59#endif
60
61template <class _LHS, class _RHS, bool = true>
62struct __has_default_three_way_comparator : false_type {};
63
64template <class _LHS, class _RHS>
65struct __has_default_three_way_comparator<_LHS, _RHS, sizeof(__default_three_way_comparator<_LHS, _RHS>) >= 0>
66 : true_type {};
67
68_LIBCPP_END_NAMESPACE_STD
69
70#endif // _LIBCPP___UTILITY_DEFAULT_THREE_WAY_COMPARATOR_H
lib/libcxx/include/__utility/in_place.h+1-1
......@@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222
2323#if _LIBCPP_STD_VER >= 17
2424
25struct _LIBCPP_EXPORTED_FROM_ABI in_place_t {
25struct in_place_t {
2626 explicit in_place_t() = default;
2727};
2828inline constexpr in_place_t in_place{};
lib/libcxx/include/__utility/integer_sequence.h+56-41
......@@ -11,63 +11,52 @@
1111
1212#include <__config>
1313#include <__cstddef/size_t.h>
14#include <__tuple/tuple_element.h>
15#include <__tuple/tuple_size.h>
1416#include <__type_traits/is_integral.h>
1517
1618#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1719# pragma GCC system_header
1820#endif
1921
22#ifndef _LIBCPP_CXX03_LANG
23
2024_LIBCPP_BEGIN_NAMESPACE_STD
2125
22template <size_t...>
23struct __tuple_indices;
26# if __has_builtin(__make_integer_seq)
27template <template <class _Tp, _Tp...> class _BaseType, class _Tp, _Tp _SequenceSize>
28using __make_integer_sequence_impl _LIBCPP_NODEBUG = __make_integer_seq<_BaseType, _Tp, _SequenceSize>;
29# else
30template <template <class _Tp, _Tp...> class _BaseType, class _Tp, _Tp _SequenceSize>
31using __make_integer_sequence_impl _LIBCPP_NODEBUG = _BaseType<_Tp, __integer_pack(_SequenceSize)...>;
32# endif
2433
25template <class _IdxType, _IdxType... _Values>
34template <class _Tp, _Tp... _Indices>
2635struct __integer_sequence {
27 template <template <class _OIdxType, _OIdxType...> class _ToIndexSeq, class _ToIndexType>
28 using __convert _LIBCPP_NODEBUG = _ToIndexSeq<_ToIndexType, _Values...>;
29
30 template <size_t _Sp>
31 using __to_tuple_indices _LIBCPP_NODEBUG = __tuple_indices<(_Values + _Sp)...>;
36 using value_type = _Tp;
37 static_assert(is_integral<_Tp>::value, "std::integer_sequence can only be instantiated with an integral type");
38 [[__nodiscard__]] static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return sizeof...(_Indices); }
3239};
3340
34#if __has_builtin(__make_integer_seq)
35template <size_t _Ep, size_t _Sp>
36using __make_indices_imp _LIBCPP_NODEBUG =
37 typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template __to_tuple_indices<_Sp>;
38#elif __has_builtin(__integer_pack)
39template <size_t _Ep, size_t _Sp>
40using __make_indices_imp _LIBCPP_NODEBUG =
41 typename __integer_sequence<size_t, __integer_pack(_Ep - _Sp)...>::template __to_tuple_indices<_Sp>;
42#else
43# error "No known way to get an integer pack from the compiler"
44#endif
41template <size_t... _Indices>
42using __index_sequence _LIBCPP_NODEBUG = __integer_sequence<size_t, _Indices...>;
4543
46#if _LIBCPP_STD_VER >= 14
44template <size_t _SequenceSize>
45using __make_index_sequence _LIBCPP_NODEBUG = __make_integer_sequence_impl<__integer_sequence, size_t, _SequenceSize>;
4746
48template <class _Tp, _Tp... _Ip>
49struct integer_sequence {
50 typedef _Tp value_type;
51 static_assert(is_integral<_Tp>::value, "std::integer_sequence can only be instantiated with an integral type");
52 static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return sizeof...(_Ip); }
53};
47template <class... _Args>
48using __index_sequence_for _LIBCPP_NODEBUG = __make_index_sequence<sizeof...(_Args)>;
49
50# if _LIBCPP_STD_VER >= 14
51
52template <class _Tp, _Tp... _Indices>
53struct integer_sequence : __integer_sequence<_Tp, _Indices...> {};
5454
5555template <size_t... _Ip>
5656using index_sequence = integer_sequence<size_t, _Ip...>;
5757
58# if __has_builtin(__make_integer_seq)
59
6058template <class _Tp, _Tp _Ep>
61using make_integer_sequence _LIBCPP_NODEBUG = __make_integer_seq<integer_sequence, _Tp, _Ep>;
62
63# elif __has_builtin(__integer_pack)
64
65template <class _Tp, _Tp _SequenceSize>
66using make_integer_sequence _LIBCPP_NODEBUG = integer_sequence<_Tp, __integer_pack(_SequenceSize)...>;
67
68# else
69# error "No known way to get an integer pack from the compiler"
70# endif
59using make_integer_sequence _LIBCPP_NODEBUG = __make_integer_sequence_impl<integer_sequence, _Tp, _Ep>;
7160
7261template <size_t _Np>
7362using make_index_sequence = make_integer_sequence<size_t, _Np>;
......@@ -75,16 +64,42 @@ using make_index_sequence = make_integer_sequence<size_t, _Np>;
7564template <class... _Tp>
7665using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
7766
78# if _LIBCPP_STD_VER >= 20
67# if _LIBCPP_STD_VER >= 20
7968// Executes __func for every element in an index_sequence.
8069template <size_t... _Index, class _Function>
8170_LIBCPP_HIDE_FROM_ABI constexpr void __for_each_index_sequence(index_sequence<_Index...>, _Function __func) {
8271 (__func.template operator()<_Index>(), ...);
8372}
84# endif // _LIBCPP_STD_VER >= 20
73# endif // _LIBCPP_STD_VER >= 20
74
75# if _LIBCPP_STD_VER >= 26
76// [intseq.binding], structured binding support
77template <class _Tp, _Tp... _Indices>
78struct tuple_size<integer_sequence<_Tp, _Indices...>> : integral_constant<size_t, sizeof...(_Indices)> {};
8579
86#endif // _LIBCPP_STD_VER >= 14
80template <size_t _Ip, class _Tp, _Tp... _Indices>
81struct tuple_element<_Ip, integer_sequence<_Tp, _Indices...>> {
82 static_assert(_Ip < sizeof...(_Indices), "Index out of bounds in std::tuple_element<> (std::integer_sequence)");
83 using type _LIBCPP_NODEBUG = _Tp;
84};
85
86template <size_t _Ip, class _Tp, _Tp... _Indices>
87struct tuple_element<_Ip, const integer_sequence<_Tp, _Indices...>> {
88 static_assert(_Ip < sizeof...(_Indices), "Index out of bounds in std::tuple_element<> (const std::integer_sequence)");
89 using type _LIBCPP_NODEBUG = _Tp;
90};
91
92template <size_t _Ip, class _Tp, _Tp... _Indices>
93[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp get(integer_sequence<_Tp, _Indices...>) noexcept {
94 static_assert(_Ip < sizeof...(_Indices), "Index out of bounds in std::get<> (std::integer_sequence)");
95 return _Indices...[_Ip];
96}
97# endif // _LIBCPP_STD_VER >= 26
98
99# endif // _LIBCPP_STD_VER >= 14
87100
88101_LIBCPP_END_NAMESPACE_STD
89102
103#endif // _LIBCPP_CXX03_LANG
104
90105#endif // _LIBCPP___UTILITY_INTEGER_SEQUENCE_H
lib/libcxx/include/__utility/lazy_synth_three_way_comparator.h created+120
......@@ -0,0 +1,120 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_LAZY_SYNTH_THREE_WAY_COMPARATOR_H
10#define _LIBCPP___UTILITY_LAZY_SYNTH_THREE_WAY_COMPARATOR_H
11
12#include <__assert>
13#include <__config>
14#include <__type_traits/conjunction.h>
15#include <__type_traits/desugars_to.h>
16#include <__type_traits/enable_if.h>
17#include <__utility/default_three_way_comparator.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23// This file implements a __lazy_synth_three_way_comparator, which tries to build an efficient three way comparison from
24// a binary comparator. That is done in multiple steps:
25// 1) Check whether the comparator desugars to a less-than operator
26// If that is the case, check whether there exists a specialization of `__default_three_way_comparator`, which
27// can be specialized to implement a three way comparator for the specific types.
28// 2) Fall back to doing a lazy less than/greater than comparison
29
30_LIBCPP_BEGIN_NAMESPACE_STD
31
32template <class _Comparator, class _LHS, class _RHS>
33struct __lazy_compare_result {
34 const _Comparator& __comp_;
35 const _LHS& __lhs_;
36 const _RHS& __rhs_;
37
38 _LIBCPP_HIDE_FROM_ABI
39 __lazy_compare_result(_LIBCPP_CTOR_LIFETIMEBOUND const _Comparator& __comp,
40 _LIBCPP_CTOR_LIFETIMEBOUND const _LHS& __lhs,
41 _LIBCPP_CTOR_LIFETIMEBOUND const _RHS& __rhs)
42 : __comp_(__comp), __lhs_(__lhs), __rhs_(__rhs) {}
43
44 _LIBCPP_HIDE_FROM_ABI bool __less() const {
45 bool __result = __comp_(__lhs_, __rhs_);
46 _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__result ? !static_cast<bool>(__comp_(__rhs_, __lhs_)) : true,
47 "Comparator does not induce a strict weak ordering");
48 return __result;
49 }
50
51 _LIBCPP_HIDE_FROM_ABI bool __greater() const {
52 bool __result = __comp_(__rhs_, __lhs_);
53 _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__result ? !static_cast<bool>(__comp_(__lhs_, __rhs_)) : true,
54 "Comparator does not induce a strict weak ordering");
55 return __result;
56 }
57};
58
59// This class provides three way comparison between _LHS and _RHS as efficiently as possible. This can be specialized if
60// a comparator only compares part of the object, potentially allowing an efficient three way comparison between the
61// subobjects. The specialization should use the __lazy_synth_three_way_comparator for the subobjects to achieve this.
62template <class _Comparator, class _LHS, class _RHS, class = void>
63struct __lazy_synth_three_way_comparator {
64 const _Comparator& __comp_;
65
66 _LIBCPP_HIDE_FROM_ABI __lazy_synth_three_way_comparator(_LIBCPP_CTOR_LIFETIMEBOUND const _Comparator& __comp)
67 : __comp_(__comp) {}
68
69 _LIBCPP_HIDE_FROM_ABI __lazy_compare_result<_Comparator, _LHS, _RHS>
70 operator()(_LIBCPP_LIFETIMEBOUND const _LHS& __lhs, _LIBCPP_LIFETIMEBOUND const _RHS& __rhs) const {
71 return __lazy_compare_result<_Comparator, _LHS, _RHS>(__comp_, __lhs, __rhs);
72 }
73};
74
75struct __eager_compare_result {
76 int __res_;
77
78 _LIBCPP_HIDE_FROM_ABI explicit __eager_compare_result(int __res) : __res_(__res) {}
79
80 _LIBCPP_HIDE_FROM_ABI bool __less() const { return __res_ < 0; }
81 _LIBCPP_HIDE_FROM_ABI bool __greater() const { return __res_ > 0; }
82};
83
84template <class _Comparator, class _LHS, class _RHS>
85struct __lazy_synth_three_way_comparator<_Comparator,
86 _LHS,
87 _RHS,
88 __enable_if_t<_And<__desugars_to<__less_tag, _Comparator, _LHS, _RHS>,
89 __has_default_three_way_comparator<_LHS, _RHS> >::value> > {
90 // This lifetimebound annotation is technically incorrect, but other specializations actually capture the lifetime of
91 // the comparator.
92 _LIBCPP_HIDE_FROM_ABI __lazy_synth_three_way_comparator(_LIBCPP_CTOR_LIFETIMEBOUND const _Comparator&) {}
93
94 // Same comment as above.
95 _LIBCPP_HIDE_FROM_ABI static __eager_compare_result
96 operator()(_LIBCPP_LIFETIMEBOUND const _LHS& __lhs, _LIBCPP_LIFETIMEBOUND const _RHS& __rhs) {
97 return __eager_compare_result(__default_three_way_comparator<_LHS, _RHS>()(__lhs, __rhs));
98 }
99};
100
101template <class _Comparator, class _LHS, class _RHS>
102struct __lazy_synth_three_way_comparator<_Comparator,
103 _LHS,
104 _RHS,
105 __enable_if_t<_And<__desugars_to<__greater_tag, _Comparator, _LHS, _RHS>,
106 __has_default_three_way_comparator<_LHS, _RHS> >::value> > {
107 // This lifetimebound annotation is technically incorrect, but other specializations actually capture the lifetime of
108 // the comparator.
109 _LIBCPP_HIDE_FROM_ABI __lazy_synth_three_way_comparator(_LIBCPP_CTOR_LIFETIMEBOUND const _Comparator&) {}
110
111 // Same comment as above.
112 _LIBCPP_HIDE_FROM_ABI static __eager_compare_result
113 operator()(_LIBCPP_LIFETIMEBOUND const _LHS& __lhs, _LIBCPP_LIFETIMEBOUND const _RHS& __rhs) {
114 return __eager_compare_result(-__default_three_way_comparator<_LHS, _RHS>()(__lhs, __rhs));
115 }
116};
117
118_LIBCPP_END_NAMESPACE_STD
119
120#endif // _LIBCPP___UTILITY_LAZY_SYNTH_THREE_WAY_COMPARATOR_H
lib/libcxx/include/__utility/pair.h+22-25
......@@ -18,7 +18,6 @@
1818#include <__fwd/array.h>
1919#include <__fwd/pair.h>
2020#include <__fwd/tuple.h>
21#include <__tuple/tuple_indices.h>
2221#include <__tuple/tuple_like_no_subrange.h>
2322#include <__tuple/tuple_size.h>
2423#include <__type_traits/common_reference.h>
......@@ -32,14 +31,13 @@
3231#include <__type_traits/is_implicitly_default_constructible.h>
3332#include <__type_traits/is_nothrow_assignable.h>
3433#include <__type_traits/is_nothrow_constructible.h>
35#include <__type_traits/is_replaceable.h>
36#include <__type_traits/is_same.h>
3734#include <__type_traits/is_swappable.h>
3835#include <__type_traits/is_trivially_relocatable.h>
3936#include <__type_traits/nat.h>
4037#include <__type_traits/unwrap_ref.h>
4138#include <__utility/declval.h>
4239#include <__utility/forward.h>
40#include <__utility/integer_sequence.h>
4341#include <__utility/move.h>
4442#include <__utility/piecewise_construct.h>
4543
......@@ -102,7 +100,6 @@ struct pair
102100 __conditional_t<__libcpp_is_trivially_relocatable<_T1>::value && __libcpp_is_trivially_relocatable<_T2>::value,
103101 pair,
104102 void>;
105 using __replaceable _LIBCPP_NODEBUG = __conditional_t<__is_replaceable_v<_T1> && __is_replaceable_v<_T2>, pair, void>;
106103
107104 _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
108105 _LIBCPP_HIDE_FROM_ABI pair(pair&&) = default;
......@@ -222,11 +219,7 @@ struct pair
222219 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
223220 pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) noexcept(
224221 is_nothrow_constructible<first_type, _Args1...>::value && is_nothrow_constructible<second_type, _Args2...>::value)
225 : pair(__pc,
226 __first_args,
227 __second_args,
228 typename __make_tuple_indices<sizeof...(_Args1)>::type(),
229 typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
222 : pair(__pc, __first_args, __second_args, __index_sequence_for<_Args1...>(), __index_sequence_for<_Args2...>()) {}
230223
231224 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair&
232225 operator=(__conditional_t<is_copy_assignable<first_type>::value && is_copy_assignable<second_type>::value,
......@@ -440,8 +433,8 @@ private:
440433 pair(piecewise_construct_t,
441434 tuple<_Args1...>& __first_args,
442435 tuple<_Args2...>& __second_args,
443 __tuple_indices<_I1...>,
444 __tuple_indices<_I2...>)
436 __index_sequence<_I1...>,
437 __index_sequence<_I2...>)
445438 : first(std::forward<_Args1>(std::get<_I1>(__first_args))...),
446439 second(std::forward<_Args2>(std::get<_I2>(__second_args))...) {}
447440#endif
......@@ -546,8 +539,8 @@ swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) noexcept(noexcept(__x
546539#endif
547540
548541template <class _T1, class _T2>
549inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<__unwrap_ref_decay_t<_T1>, __unwrap_ref_decay_t<_T2> >
550make_pair(_T1&& __t1, _T2&& __t2) {
542[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
543pair<__unwrap_ref_decay_t<_T1>, __unwrap_ref_decay_t<_T2> > make_pair(_T1&& __t1, _T2&& __t2) {
551544 return pair<__unwrap_ref_decay_t<_T1>, __unwrap_ref_decay_t<_T2> >(std::forward<_T1>(__t1), std::forward<_T2>(__t2));
552545}
553546
......@@ -619,67 +612,71 @@ struct __get_pair<1> {
619612};
620613
621614template <size_t _Ip, class _T1, class _T2>
622inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&
615[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
616typename tuple_element<_Ip, pair<_T1, _T2> >::type&
623617get(pair<_T1, _T2>& __p) _NOEXCEPT {
624618 return __get_pair<_Ip>::get(__p);
625619}
626620
627621template <size_t _Ip, class _T1, class _T2>
628inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
622[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
623_LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
629624get(const pair<_T1, _T2>& __p) _NOEXCEPT {
630625 return __get_pair<_Ip>::get(__p);
631626}
632627
633628template <size_t _Ip, class _T1, class _T2>
634inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
629[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
630typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
635631get(pair<_T1, _T2>&& __p) _NOEXCEPT {
636632 return __get_pair<_Ip>::get(std::move(__p));
637633}
638634
639635template <size_t _Ip, class _T1, class _T2>
640inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
636[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
637_LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
641638get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
642639 return __get_pair<_Ip>::get(std::move(__p));
643640}
644641
645642#if _LIBCPP_STD_VER >= 14
646643template <class _T1, class _T2>
647inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {
644[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {
648645 return __p.first;
649646}
650647
651648template <class _T1, class _T2>
652inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT {
649[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT {
653650 return __p.first;
654651}
655652
656653template <class _T1, class _T2>
657inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
654[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
658655 return std::forward<_T1&&>(__p.first);
659656}
660657
661658template <class _T1, class _T2>
662inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T1, _T2> const&& __p) _NOEXCEPT {
659[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T1, _T2> const&& __p) _NOEXCEPT {
663660 return std::forward<_T1 const&&>(__p.first);
664661}
665662
666663template <class _T2, class _T1>
667inline _LIBCPP_HIDE_FROM_ABI constexpr _T2& get(pair<_T1, _T2>& __p) _NOEXCEPT {
664[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T2& get(pair<_T1, _T2>& __p) _NOEXCEPT {
668665 return __p.second;
669666}
670667
671668template <class _T2, class _T1>
672inline _LIBCPP_HIDE_FROM_ABI constexpr _T2 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT {
669[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T2 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT {
673670 return __p.second;
674671}
675672
676673template <class _T2, class _T1>
677inline _LIBCPP_HIDE_FROM_ABI constexpr _T2&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
674[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T2&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
678675 return std::forward<_T2&&>(__p.second);
679676}
680677
681678template <class _T2, class _T1>
682inline _LIBCPP_HIDE_FROM_ABI constexpr _T2 const&& get(pair<_T1, _T2> const&& __p) _NOEXCEPT {
679[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T2 const&& get(pair<_T1, _T2> const&& __p) _NOEXCEPT {
683680 return std::forward<_T2 const&&>(__p.second);
684681}
685682
lib/libcxx/include/__utility/scope_guard.h+2
......@@ -43,6 +43,8 @@ public:
4343#endif
4444};
4545
46_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__scope_guard);
47
4648template <class _Func>
4749_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __scope_guard<_Func> __make_scope_guard(_Func __func) {
4850 return __scope_guard<_Func>(std::move(__func));
lib/libcxx/include/__utility/try_key_extraction.h created+114
......@@ -0,0 +1,114 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_TRY_EXTRACT_KEY_H
10#define _LIBCPP___UTILITY_TRY_EXTRACT_KEY_H
11
12#include <__config>
13#include <__fwd/pair.h>
14#include <__fwd/tuple.h>
15#include <__type_traits/enable_if.h>
16#include <__type_traits/is_same.h>
17#include <__type_traits/remove_const.h>
18#include <__type_traits/remove_const_ref.h>
19#include <__utility/declval.h>
20#include <__utility/forward.h>
21#include <__utility/piecewise_construct.h>
22#include <__utility/priority_tag.h>
23
24#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25# pragma GCC system_header
26#endif
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30template <class _KeyT, class _Ret, class _WithKey, class _WithoutKey, class... _Args>
31_LIBCPP_HIDE_FROM_ABI _Ret
32__try_key_extraction_impl(__priority_tag<0>, _WithKey, _WithoutKey __without_key, _Args&&... __args) {
33 return __without_key(std::forward<_Args>(__args)...);
34}
35
36template <class _KeyT,
37 class _Ret,
38 class _WithKey,
39 class _WithoutKey,
40 class _Arg,
41 __enable_if_t<is_same<_KeyT, __remove_const_ref_t<_Arg> >::value, int> = 0>
42_LIBCPP_HIDE_FROM_ABI _Ret
43__try_key_extraction_impl(__priority_tag<1>, _WithKey __with_key, _WithoutKey, _Arg&& __arg) {
44 return __with_key(__arg, std::forward<_Arg>(__arg));
45}
46
47template <class _KeyT,
48 class _Ret,
49 class _WithKey,
50 class _WithoutKey,
51 class _Arg,
52 __enable_if_t<__is_pair_v<__remove_const_ref_t<_Arg> > &&
53 is_same<__remove_const_t<typename __remove_const_ref_t<_Arg>::first_type>, _KeyT>::value,
54 int> = 0>
55_LIBCPP_HIDE_FROM_ABI _Ret
56__try_key_extraction_impl(__priority_tag<1>, _WithKey __with_key, _WithoutKey, _Arg&& __arg) {
57 return __with_key(__arg.first, std::forward<_Arg>(__arg));
58}
59
60template <class _KeyT,
61 class _Ret,
62 class _WithKey,
63 class _WithoutKey,
64 class _Arg1,
65 class _Arg2,
66 __enable_if_t<is_same<_KeyT, __remove_const_ref_t<_Arg1> >::value, int> = 0>
67_LIBCPP_HIDE_FROM_ABI _Ret
68__try_key_extraction_impl(__priority_tag<1>, _WithKey __with_key, _WithoutKey, _Arg1&& __arg1, _Arg2&& __arg2) {
69 return __with_key(__arg1, std::forward<_Arg1>(__arg1), std::forward<_Arg2>(__arg2));
70}
71
72#ifndef _LIBCPP_CXX03_LANG
73template <class _KeyT,
74 class _Ret,
75 class _WithKey,
76 class _WithoutKey,
77 class _PiecewiseConstruct,
78 class _Tuple1,
79 class _Tuple2,
80 __enable_if_t<is_same<__remove_const_ref_t<_PiecewiseConstruct>, piecewise_construct_t>::value &&
81 __is_tuple_v<_Tuple1> && tuple_size<_Tuple1>::value == 1 &&
82 is_same<__remove_const_ref_t<typename tuple_element<0, _Tuple1>::type>, _KeyT>::value,
83 int> = 0>
84_LIBCPP_HIDE_FROM_ABI _Ret __try_key_extraction_impl(
85 __priority_tag<1>,
86 _WithKey __with_key,
87 _WithoutKey,
88 _PiecewiseConstruct&& __pc,
89 _Tuple1&& __tuple1,
90 _Tuple2&& __tuple2) {
91 return __with_key(
92 std::get<0>(__tuple1),
93 std::forward<_PiecewiseConstruct>(__pc),
94 std::forward<_Tuple1>(__tuple1),
95 std::forward<_Tuple2>(__tuple2));
96}
97#endif // _LIBCPP_CXX03_LANG
98
99// This function tries extracting the given _KeyT from _Args...
100// If it succeeds to extract the key, it calls the `__with_key` function with the extracted key and all of the
101// arguments. Otherwise it calls the `__without_key` function with all of the arguments.
102//
103// Both `__with_key` and `__without_key` must take all arguments by reference.
104template <class _KeyT, class _WithKey, class _WithoutKey, class... _Args>
105_LIBCPP_HIDE_FROM_ABI decltype(std::declval<_WithoutKey>()(std::declval<_Args>()...))
106__try_key_extraction(_WithKey __with_key, _WithoutKey __without_key, _Args&&... __args) {
107 using _Ret = decltype(__without_key(std::forward<_Args>(__args)...));
108 return std::__try_key_extraction_impl<_KeyT, _Ret>(
109 __priority_tag<1>(), __with_key, __without_key, std::forward<_Args>(__args)...);
110}
111
112_LIBCPP_END_NAMESPACE_STD
113
114#endif // _LIBCPP___UTILITY_TRY_EXTRACT_KEY_H
lib/libcxx/include/__vector/vector.h+187-160
......@@ -12,18 +12,17 @@
1212#include <__algorithm/copy.h>
1313#include <__algorithm/copy_n.h>
1414#include <__algorithm/fill_n.h>
15#include <__algorithm/iterator_operations.h>
1516#include <__algorithm/max.h>
1617#include <__algorithm/min.h>
1718#include <__algorithm/move.h>
1819#include <__algorithm/move_backward.h>
19#include <__algorithm/ranges_copy_n.h>
2020#include <__algorithm/rotate.h>
2121#include <__assert>
2222#include <__config>
2323#include <__debug_utils/sanitizers.h>
2424#include <__format/enable_insertable.h>
2525#include <__fwd/vector.h>
26#include <__iterator/advance.h>
2726#include <__iterator/bounded_iter.h>
2827#include <__iterator/concepts.h>
2928#include <__iterator/distance.h>
......@@ -43,6 +42,7 @@
4342#include <__memory/temp_value.h>
4443#include <__memory/uninitialized_algorithms.h>
4544#include <__ranges/access.h>
45#include <__ranges/as_rvalue_view.h>
4646#include <__ranges/concepts.h>
4747#include <__ranges/container_compatible_range.h>
4848#include <__ranges/from_range.h>
......@@ -55,7 +55,6 @@
5555#include <__type_traits/is_nothrow_assignable.h>
5656#include <__type_traits/is_nothrow_constructible.h>
5757#include <__type_traits/is_pointer.h>
58#include <__type_traits/is_replaceable.h>
5958#include <__type_traits/is_same.h>
6059#include <__type_traits/is_trivially_relocatable.h>
6160#include <__type_traits/type_identity.h>
......@@ -86,6 +85,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
8685
8786template <class _Tp, class _Allocator /* = allocator<_Tp> */>
8887class vector {
88 template <class _Up, class _Alloc>
89 using __split_buffer _LIBCPP_NODEBUG = std::__split_buffer<_Up, _Alloc, __split_buffer_pointer_layout>;
90
8991public:
9092 //
9193 // Types
......@@ -113,7 +115,7 @@ public:
113115 using reverse_iterator = std::reverse_iterator<iterator>;
114116 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
115117
116 // A vector containers the following members which may be trivially relocatable:
118 // A vector contains the following members which may be trivially relocatable:
117119 // - pointer: may be trivially relocatable, so it's checked
118120 // - allocator_type: may be trivially relocatable, so it's checked
119121 // vector doesn't contain any self-references, so it's trivially relocatable if its members are.
......@@ -121,10 +123,6 @@ public:
121123 __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
122124 vector,
123125 void>;
124 using __replaceable _LIBCPP_NODEBUG =
125 __conditional_t<__is_replaceable_v<pointer> && __container_allocator_is_replaceable<__alloc_traits>::value,
126 vector,
127 void>;
128126
129127 static_assert(__check_valid_allocator<allocator_type>::value, "");
130128 static_assert(is_same<typename allocator_type::value_type, value_type>::value,
......@@ -174,7 +172,7 @@ public:
174172 __guard.__complete();
175173 }
176174
177 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
175 template <__enable_if_t<__is_allocator_v<_Allocator>, int> = 0>
178176 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
179177 vector(size_type __n, const value_type& __x, const allocator_type& __a)
180178 : __alloc_(__a) {
......@@ -317,7 +315,7 @@ public:
317315 is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value,
318316 int> = 0>
319317 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(_ForwardIterator __first, _ForwardIterator __last) {
320 __assign_with_size(__first, __last, std::distance(__first, __last));
318 __assign_with_size<_ClassicAlgPolicy>(__first, __last, std::distance(__first, __last));
321319 }
322320
323321#if _LIBCPP_STD_VER >= 23
......@@ -325,7 +323,7 @@ public:
325323 _LIBCPP_HIDE_FROM_ABI constexpr void assign_range(_Range&& __range) {
326324 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
327325 auto __n = static_cast<size_type>(ranges::distance(__range));
328 __assign_with_size(ranges::begin(__range), ranges::end(__range), __n);
326 __assign_with_size<_RangeAlgPolicy>(ranges::begin(__range), ranges::end(__range), __n);
329327
330328 } else {
331329 __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
......@@ -341,59 +339,67 @@ public:
341339 }
342340#endif
343341
344 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
342 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
345343 return this->__alloc_;
346344 }
347345
348346 //
349347 // Iterators
350348 //
351 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
349 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
352350 return __make_iter(__add_alignment_assumption(this->__begin_));
353351 }
354 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
352 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
355353 return __make_iter(__add_alignment_assumption(this->__begin_));
356354 }
357 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
355 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
358356 return __make_iter(__add_alignment_assumption(this->__end_));
359357 }
360 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
358 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
361359 return __make_iter(__add_alignment_assumption(this->__end_));
362360 }
363361
364 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT {
362 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT {
365363 return reverse_iterator(end());
366364 }
367 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
365 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator
366 rbegin() const _NOEXCEPT {
368367 return const_reverse_iterator(end());
369368 }
370 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT {
369 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT {
371370 return reverse_iterator(begin());
372371 }
373 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
372 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
374373 return const_reverse_iterator(begin());
375374 }
376375
377 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
378 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
379 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT {
376 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
377 return begin();
378 }
379 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
380 return end();
381 }
382 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator
383 crbegin() const _NOEXCEPT {
380384 return rbegin();
381385 }
382 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
386 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {
387 return rend();
388 }
383389
384390 //
385391 // [vector.capacity], capacity
386392 //
387 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
393 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
388394 return static_cast<size_type>(this->__end_ - this->__begin_);
389395 }
390 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
396 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
391397 return static_cast<size_type>(this->__cap_ - this->__begin_);
392398 }
393399 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
394400 return this->__begin_ == this->__end_;
395401 }
396 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
402 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
397403 return std::min<size_type>(__alloc_traits::max_size(this->__alloc_), numeric_limits<difference_type>::max());
398404 }
399405 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n);
......@@ -402,38 +408,39 @@ public:
402408 //
403409 // element access
404410 //
405 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __n) _NOEXCEPT {
411 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __n) _NOEXCEPT {
406412 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
407413 return this->__begin_[__n];
408414 }
409 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __n) const _NOEXCEPT {
415 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference
416 operator[](size_type __n) const _NOEXCEPT {
410417 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds");
411418 return this->__begin_[__n];
412419 }
413 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference at(size_type __n) {
420 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference at(size_type __n) {
414421 if (__n >= size())
415422 this->__throw_out_of_range();
416423 return this->__begin_[__n];
417424 }
418 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __n) const {
425 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __n) const {
419426 if (__n >= size())
420427 this->__throw_out_of_range();
421428 return this->__begin_[__n];
422429 }
423430
424 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT {
431 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT {
425432 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
426433 return *this->__begin_;
427434 }
428 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {
435 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {
429436 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector");
430437 return *this->__begin_;
431438 }
432 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {
439 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {
433440 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
434441 return *(this->__end_ - 1);
435442 }
436 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
443 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
437444 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector");
438445 return *(this->__end_ - 1);
439446 }
......@@ -441,11 +448,11 @@ public:
441448 //
442449 // [vector.data], data access
443450 //
444 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI value_type* data() _NOEXCEPT {
451 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI value_type* data() _NOEXCEPT {
445452 return std::__to_address(this->__begin_);
446453 }
447454
448 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const value_type* data() const _NOEXCEPT {
455 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const value_type* data() const _NOEXCEPT {
449456 return std::__to_address(this->__begin_);
450457 }
451458
......@@ -478,7 +485,21 @@ public:
478485#if _LIBCPP_STD_VER >= 23
479486 template <_ContainerCompatibleRange<_Tp> _Range>
480487 _LIBCPP_HIDE_FROM_ABI constexpr void append_range(_Range&& __range) {
481 insert_range(end(), std::forward<_Range>(__range));
488 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
489 auto __len = ranges::distance(__range);
490 if (__len <= __cap_ - __end_) {
491 __construct_at_end(ranges::begin(__range), ranges::end(__range), __len);
492 } else {
493 __split_buffer<value_type, allocator_type> __buffer(__recommend(size() + __len), size(), __alloc_);
494 __buffer.__construct_at_end_with_size(ranges::begin(__range), __len);
495 __swap_out_circular_buffer(__buffer);
496 }
497 } else {
498 vector __buffer(__alloc_);
499 for (auto&& __val : __range)
500 __buffer.emplace_back(std::forward<decltype(__val)>(__val));
501 append_range(ranges::as_rvalue_view(__buffer));
502 }
482503 }
483504#endif
484505
......@@ -512,7 +533,7 @@ public:
512533 int> = 0>
513534 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
514535 insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) {
515 return __insert_with_size(__position, __first, __last, std::distance(__first, __last));
536 return __insert_with_size<_ClassicAlgPolicy>(__position, __first, __last, std::distance(__first, __last));
516537 }
517538
518539#if _LIBCPP_STD_VER >= 23
......@@ -520,7 +541,7 @@ public:
520541 _LIBCPP_HIDE_FROM_ABI constexpr iterator insert_range(const_iterator __position, _Range&& __range) {
521542 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
522543 auto __n = static_cast<size_type>(ranges::distance(__range));
523 return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n);
544 return __insert_with_size<_RangeAlgPolicy>(__position, ranges::begin(__range), ranges::end(__range), __n);
524545
525546 } else {
526547 return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
......@@ -613,12 +634,13 @@ private:
613634 // The `_Iterator` in `*_with_size` functions can be input-only only if called from `*_range` (since C++23).
614635 // Otherwise, `_Iterator` is a forward iterator.
615636
616 template <class _Iterator, class _Sentinel>
637 template <class _AlgPolicy, class _Iterator, class _Sentinel>
617638 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
618639 __assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n);
619640
620 template <class _Iterator,
621 __enable_if_t<!is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0>
641 template <class _AlgPolicy,
642 class _Iterator,
643 __enable_if_t<!is_same<__policy_value_type<_AlgPolicy, _Iterator>, value_type>::value, int> = 0>
622644 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
623645 __insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) {
624646 for (pointer __end_position = __position + __n; __position != __end_position; ++__position, (void)++__first) {
......@@ -627,25 +649,19 @@ private:
627649 }
628650 }
629651
630 template <class _Iterator,
631 __enable_if_t<is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0>
652 template <class _AlgPolicy,
653 class _Iterator,
654 __enable_if_t<is_same<__policy_value_type<_AlgPolicy, _Iterator>, value_type>::value, int> = 0>
632655 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
633656 __insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) {
634#if _LIBCPP_STD_VER >= 23
635 if constexpr (!forward_iterator<_Iterator>) { // Handles input-only sized ranges for insert_range
636 ranges::copy_n(std::move(__first), __n, __position);
637 } else
638#endif
639 {
640 std::copy_n(__first, __n, __position);
641 }
657 std::__copy_n<_AlgPolicy>(std::move(__first), __n, __position);
642658 }
643659
644660 template <class _InputIterator, class _Sentinel>
645661 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
646662 __insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last);
647663
648 template <class _Iterator, class _Sentinel>
664 template <class _AlgPolicy, class _Iterator, class _Sentinel>
649665 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
650666 __insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n);
651667
......@@ -653,9 +669,6 @@ private:
653669 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
654670 __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n);
655671
656 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);
657 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x);
658
659672 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator __make_iter(pointer __p) _NOEXCEPT {
660673#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR
661674 // Bound the iterator according to the capacity, rather than the size.
......@@ -689,9 +702,9 @@ private:
689702 }
690703
691704 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
692 __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v);
705 __swap_out_circular_buffer(__split_buffer<value_type, allocator_type>& __v);
693706 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer
694 __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p);
707 __swap_out_circular_buffer(__split_buffer<value_type, allocator_type>& __v, pointer __p);
695708 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
696709 __move_range(pointer __from_s, pointer __from_e, pointer __to);
697710 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign(vector& __c, true_type)
......@@ -811,26 +824,44 @@ private:
811824 __add_alignment_assumption(_Ptr __p) _NOEXCEPT {
812825 return __p;
813826 }
827
828 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_layouts(__split_buffer<_Tp, allocator_type>& __sb) {
829 auto __vector_begin = __begin_;
830 auto __vector_sentinel = __end_;
831 auto __vector_cap = __cap_;
832
833 auto __sb_begin = __sb.begin();
834 auto __sb_sentinel = __sb.__raw_sentinel();
835 auto __sb_cap = __sb.__raw_capacity();
836
837 // TODO: replace with __set_valid_range and __set_capacity when vector supports it.
838 __begin_ = __sb_begin;
839 __end_ = __sb_sentinel;
840 __cap_ = __sb_cap;
841
842 __sb.__set_valid_range(__vector_begin, __vector_sentinel);
843 __sb.__set_capacity(__vector_cap);
844 }
814845};
815846
816847#if _LIBCPP_STD_VER >= 17
817848template <class _InputIterator,
818 class _Alloc = allocator<__iter_value_type<_InputIterator>>,
849 class _Alloc = allocator<__iterator_value_type<_InputIterator>>,
819850 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
820 class = enable_if_t<__is_allocator<_Alloc>::value> >
821vector(_InputIterator, _InputIterator) -> vector<__iter_value_type<_InputIterator>, _Alloc>;
851 class = enable_if_t<__is_allocator_v<_Alloc>>>
852vector(_InputIterator, _InputIterator) -> vector<__iterator_value_type<_InputIterator>, _Alloc>;
822853
823854template <class _InputIterator,
824855 class _Alloc,
825856 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
826 class = enable_if_t<__is_allocator<_Alloc>::value> >
827vector(_InputIterator, _InputIterator, _Alloc) -> vector<__iter_value_type<_InputIterator>, _Alloc>;
857 class = enable_if_t<__is_allocator_v<_Alloc>>>
858vector(_InputIterator, _InputIterator, _Alloc) -> vector<__iterator_value_type<_InputIterator>, _Alloc>;
828859#endif
829860
830861#if _LIBCPP_STD_VER >= 23
831862template <ranges::input_range _Range,
832863 class _Alloc = allocator<ranges::range_value_t<_Range>>,
833 class = enable_if_t<__is_allocator<_Alloc>::value> >
864 class = enable_if_t<__is_allocator_v<_Alloc>>>
834865vector(from_range_t, _Range&&, _Alloc = _Alloc()) -> vector<ranges::range_value_t<_Range>, _Alloc>;
835866#endif
836867
......@@ -839,17 +870,16 @@ vector(from_range_t, _Range&&, _Alloc = _Alloc()) -> vector<ranges::range_value_
839870// function has a strong exception guarantee.
840871template <class _Tp, class _Allocator>
841872_LIBCPP_CONSTEXPR_SINCE_CXX20 void
842vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v) {
873vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type>& __v) {
843874 __annotate_delete();
844 auto __new_begin = __v.__begin_ - (__end_ - __begin_);
875 auto __new_begin = __v.begin() - size();
845876 std::__uninitialized_allocator_relocate(
846877 this->__alloc_, std::__to_address(__begin_), std::__to_address(__end_), std::__to_address(__new_begin));
847 __v.__begin_ = __new_begin;
878 __v.__set_valid_range(__new_begin, __v.end());
848879 __end_ = __begin_; // All the objects have been destroyed by relocating them.
849 std::swap(this->__begin_, __v.__begin_);
850 std::swap(this->__end_, __v.__end_);
851 std::swap(this->__cap_, __v.__cap_);
852 __v.__first_ = __v.__begin_;
880
881 __swap_layouts(__v);
882 __v.__set_data(__v.begin());
853883 __annotate_new(size());
854884}
855885
......@@ -859,27 +889,25 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
859889// function has a strong exception guarantee if __begin_ == __p || __end_ == __p.
860890template <class _Tp, class _Allocator>
861891_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::pointer
862vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p) {
892vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type>& __v, pointer __p) {
863893 __annotate_delete();
864 pointer __ret = __v.__begin_;
894 pointer __ret = __v.begin();
865895
866896 // Relocate [__p, __end_) first to avoid having a hole in [__begin_, __end_)
867897 // in case something in [__begin_, __p) throws.
868898 std::__uninitialized_allocator_relocate(
869 this->__alloc_, std::__to_address(__p), std::__to_address(__end_), std::__to_address(__v.__end_));
870 __v.__end_ += (__end_ - __p);
899 this->__alloc_, std::__to_address(__p), std::__to_address(__end_), std::__to_address(__v.end()));
900 auto __relocated_so_far = __end_ - __p;
901 __v.__set_sentinel(__v.end() + __relocated_so_far);
871902 __end_ = __p; // The objects in [__p, __end_) have been destroyed by relocating them.
872 auto __new_begin = __v.__begin_ - (__p - __begin_);
903 auto __new_begin = __v.begin() - (__p - __begin_);
873904
874905 std::__uninitialized_allocator_relocate(
875906 this->__alloc_, std::__to_address(__begin_), std::__to_address(__p), std::__to_address(__new_begin));
876 __v.__begin_ = __new_begin;
877 __end_ = __begin_; // All the objects have been destroyed by relocating them.
878
879 std::swap(this->__begin_, __v.__begin_);
880 std::swap(this->__end_, __v.__end_);
881 std::swap(this->__cap_, __v.__cap_);
882 __v.__first_ = __v.__begin_;
907 __v.__set_valid_range(__new_begin, __v.end());
908 __end_ = __begin_; // All the objects have been destroyed by relocating them.
909 __swap_layouts(__v);
910 __v.__set_data(__v.begin());
883911 __annotate_new(size());
884912 return __ret;
885913}
......@@ -945,36 +973,6 @@ vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __
945973 __tx.__pos_ = std::__uninitialized_allocator_copy(this->__alloc_, std::move(__first), std::move(__last), __tx.__pos_);
946974}
947975
948// Default constructs __n objects starting at __end_
949// throws if construction throws
950// Postcondition: size() == size() + __n
951// Exception safety: strong.
952template <class _Tp, class _Allocator>
953_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__append(size_type __n) {
954 if (static_cast<size_type>(this->__cap_ - this->__end_) >= __n)
955 this->__construct_at_end(__n);
956 else {
957 __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), this->__alloc_);
958 __v.__construct_at_end(__n);
959 __swap_out_circular_buffer(__v);
960 }
961}
962
963// Default constructs __n objects starting at __end_
964// throws if construction throws
965// Postcondition: size() == size() + __n
966// Exception safety: strong.
967template <class _Tp, class _Allocator>
968_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__append(size_type __n, const_reference __x) {
969 if (static_cast<size_type>(this->__cap_ - this->__end_) >= __n)
970 this->__construct_at_end(__n, __x);
971 else {
972 __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), this->__alloc_);
973 __v.__construct_at_end(__n, __x);
974 __swap_out_circular_buffer(__v);
975 }
976}
977
978976template <class _Tp, class _Allocator>
979977_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocator>::vector(vector&& __x)
980978#if _LIBCPP_STD_VER >= 17
......@@ -1051,20 +1049,14 @@ vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __l
10511049}
10521050
10531051template <class _Tp, class _Allocator>
1054template <class _Iterator, class _Sentinel>
1052template <class _AlgPolicy, class _Iterator, class _Sentinel>
10551053_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
10561054vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n) {
10571055 size_type __new_size = static_cast<size_type>(__n);
10581056 if (__new_size <= capacity()) {
10591057 if (__new_size > size()) {
1060#if _LIBCPP_STD_VER >= 23
1061 auto __mid = ranges::copy_n(std::move(__first), size(), this->__begin_).in;
1058 auto __mid = std::__copy_n<_AlgPolicy>(std::move(__first), size(), this->__begin_).first;
10621059 __construct_at_end(std::move(__mid), std::move(__last), __new_size - size());
1063#else
1064 _Iterator __mid = std::next(__first, size());
1065 std::copy(__first, __mid, this->__begin_);
1066 __construct_at_end(__mid, __last, __new_size - size());
1067#endif
10681060 } else {
10691061 pointer __m = std::__copy(std::move(__first), __last, this->__begin_).second;
10701062 this->__destruct_at_end(__m);
......@@ -1097,7 +1089,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::reserve(size_type __
10971089 if (__n > capacity()) {
10981090 if (__n > max_size())
10991091 this->__throw_length_error();
1100 __split_buffer<value_type, allocator_type&> __v(__n, size(), this->__alloc_);
1092 __split_buffer<value_type, allocator_type> __v(__n, size(), this->__alloc_);
11011093 __swap_out_circular_buffer(__v);
11021094 }
11031095}
......@@ -1108,7 +1100,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::shrink_to_fit() _NOE
11081100#if _LIBCPP_HAS_EXCEPTIONS
11091101 try {
11101102#endif // _LIBCPP_HAS_EXCEPTIONS
1111 __split_buffer<value_type, allocator_type&> __v(size(), size(), this->__alloc_);
1103 __split_buffer<value_type, allocator_type> __v(size(), size(), this->__alloc_);
11121104 // The Standard mandates shrink_to_fit() does not increase the capacity.
11131105 // With equal capacity keep the existing buffer. This avoids extra work
11141106 // due to swapping the elements.
......@@ -1125,14 +1117,33 @@ template <class _Tp, class _Allocator>
11251117template <class... _Args>
11261118_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::pointer
11271119vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args) {
1128 __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), size(), this->__alloc_);
1120 __split_buffer<value_type, allocator_type> __v(__recommend(size() + 1), size(), this->__alloc_);
11291121 // __v.emplace_back(std::forward<_Args>(__args)...);
1130 __alloc_traits::construct(this->__alloc_, std::__to_address(__v.__end_), std::forward<_Args>(__args)...);
1131 __v.__end_++;
1122 pointer __end = __v.end();
1123 __alloc_traits::construct(this->__alloc_, std::__to_address(__end), std::forward<_Args>(__args)...);
1124 __v.__set_sentinel(++__end);
11321125 __swap_out_circular_buffer(__v);
11331126 return this->__end_;
11341127}
11351128
1129// This makes the compiler inline `__else()` if `__cond` is known to be false. Currently LLVM doesn't do that without
1130// the `__builtin_constant_p`, since it considers `__else` unlikely even through it's known to be run.
1131// See https://llvm.org/PR154292
1132template <class _If, class _Else>
1133_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __if_likely_else(bool __cond, _If __if, _Else __else) {
1134 if (__builtin_constant_p(__cond)) {
1135 if (__cond)
1136 __if();
1137 else
1138 __else();
1139 } else {
1140 if (__cond) [[__likely__]]
1141 __if();
1142 else
1143 __else();
1144 }
1145}
1146
11361147template <class _Tp, class _Allocator>
11371148template <class... _Args>
11381149_LIBCPP_CONSTEXPR_SINCE_CXX20 inline
......@@ -1143,12 +1154,14 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 inline
11431154#endif
11441155 vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) {
11451156 pointer __end = this->__end_;
1146 if (__end < this->__cap_) {
1147 __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
1148 ++__end;
1149 } else {
1150 __end = __emplace_back_slow_path(std::forward<_Args>(__args)...);
1151 }
1157 std::__if_likely_else(
1158 __end < this->__cap_,
1159 [&] {
1160 __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
1161 ++__end;
1162 },
1163 [&] { __end = __emplace_back_slow_path(std::forward<_Args>(__args)...); });
1164
11521165 this->__end_ = __end;
11531166#if _LIBCPP_STD_VER >= 17
11541167 return *(__end - 1);
......@@ -1207,7 +1220,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
12071220 *__p = *__xr;
12081221 }
12091222 } else {
1210 __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
1223 __split_buffer<value_type, allocator_type> __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
12111224 __v.emplace_back(__x);
12121225 __p = __swap_out_circular_buffer(__v, __p);
12131226 }
......@@ -1226,7 +1239,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) {
12261239 *__p = std::move(__x);
12271240 }
12281241 } else {
1229 __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
1242 __split_buffer<value_type, allocator_type> __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
12301243 __v.emplace_back(std::move(__x));
12311244 __p = __swap_out_circular_buffer(__v, __p);
12321245 }
......@@ -1247,7 +1260,7 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) {
12471260 *__p = std::move(__tmp.get());
12481261 }
12491262 } else {
1250 __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
1263 __split_buffer<value_type, allocator_type> __v(__recommend(size() + 1), __p - this->__begin_, this->__alloc_);
12511264 __v.emplace_back(std::forward<_Args>(__args)...);
12521265 __p = __swap_out_circular_buffer(__v, __p);
12531266 }
......@@ -1275,7 +1288,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_
12751288 std::fill_n(__p, __n, *__xr);
12761289 }
12771290 } else {
1278 __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, this->__alloc_);
1291 __split_buffer<value_type, allocator_type> __v(__recommend(size() + __n), __p - this->__begin_, this->__alloc_);
12791292 __v.__construct_at_end(__n, __x);
12801293 __p = __swap_out_circular_buffer(__v, __p);
12811294 }
......@@ -1296,28 +1309,28 @@ vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _Inpu
12961309 if (__first == __last)
12971310 (void)std::rotate(__p, __old_last, this->__end_);
12981311 else {
1299 __split_buffer<value_type, allocator_type&> __v(__alloc_);
1312 __split_buffer<value_type, allocator_type> __v(__alloc_);
13001313 auto __guard = std::__make_exception_guard(
13011314 _AllocatorDestroyRangeReverse<allocator_type, pointer>(__alloc_, __old_last, this->__end_));
13021315 __v.__construct_at_end_with_sentinel(std::move(__first), std::move(__last));
1303 __split_buffer<value_type, allocator_type&> __merged(
1316 __split_buffer<value_type, allocator_type> __merged(
13041317 __recommend(size() + __v.size()), __off, __alloc_); // has `__off` positions available at the front
13051318 std::__uninitialized_allocator_relocate(
1306 __alloc_, std::__to_address(__old_last), std::__to_address(this->__end_), std::__to_address(__merged.__end_));
1319 __alloc_, std::__to_address(__old_last), std::__to_address(this->__end_), std::__to_address(__merged.end()));
13071320 __guard.__complete(); // Release the guard once objects in [__old_last_, __end_) have been successfully relocated.
1308 __merged.__end_ += this->__end_ - __old_last;
1321 __merged.__set_sentinel(__merged.end() + (this->__end_ - __old_last));
13091322 this->__end_ = __old_last;
13101323 std::__uninitialized_allocator_relocate(
1311 __alloc_, std::__to_address(__v.__begin_), std::__to_address(__v.__end_), std::__to_address(__merged.__end_));
1312 __merged.__end_ += __v.size();
1313 __v.__end_ = __v.__begin_;
1324 __alloc_, std::__to_address(__v.begin()), std::__to_address(__v.end()), std::__to_address(__merged.end()));
1325 __merged.__set_sentinel(__merged.size() + __v.size());
1326 __v.__set_sentinel(__v.begin());
13141327 __p = __swap_out_circular_buffer(__merged, __p);
13151328 }
13161329 return __make_iter(__p);
13171330}
13181331
13191332template <class _Tp, class _Allocator>
1320template <class _Iterator, class _Sentinel>
1333template <class _AlgPolicy, class _Iterator, class _Sentinel>
13211334_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
13221335vector<_Tp, _Allocator>::__insert_with_size(
13231336 const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n) {
......@@ -1338,15 +1351,15 @@ vector<_Tp, _Allocator>::__insert_with_size(
13381351 __construct_at_end(__m, __last, __n - __dx);
13391352 if (__dx > 0) {
13401353 __move_range(__p, __old_last, __p + __n);
1341 __insert_assign_n_unchecked(__first, __dx, __p);
1354 __insert_assign_n_unchecked<_AlgPolicy>(__first, __dx, __p);
13421355 }
13431356 }
13441357 } else {
13451358 __move_range(__p, __old_last, __p + __n);
1346 __insert_assign_n_unchecked(std::move(__first), __n, __p);
1359 __insert_assign_n_unchecked<_AlgPolicy>(std::move(__first), __n, __p);
13471360 }
13481361 } else {
1349 __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, this->__alloc_);
1362 __split_buffer<value_type, allocator_type> __v(__recommend(size() + __n), __p - this->__begin_, this->__alloc_);
13501363 __v.__construct_at_end_with_size(std::move(__first), __n);
13511364 __p = __swap_out_circular_buffer(__v, __p);
13521365 }
......@@ -1355,21 +1368,35 @@ vector<_Tp, _Allocator>::__insert_with_size(
13551368}
13561369
13571370template <class _Tp, class _Allocator>
1358_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __sz) {
1359 size_type __cs = size();
1360 if (__cs < __sz)
1361 this->__append(__sz - __cs);
1362 else if (__cs > __sz)
1363 this->__destruct_at_end(this->__begin_ + __sz);
1371_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __new_size) {
1372 size_type __current_size = size();
1373 if (__current_size < __new_size) {
1374 if (__new_size <= capacity()) {
1375 __construct_at_end(__new_size - __current_size);
1376 } else {
1377 __split_buffer<value_type, allocator_type> __v(__recommend(__new_size), __current_size, __alloc_);
1378 __v.__construct_at_end(__new_size - __current_size);
1379 __swap_out_circular_buffer(__v);
1380 }
1381 } else if (__current_size > __new_size) {
1382 this->__destruct_at_end(this->__begin_ + __new_size);
1383 }
13641384}
13651385
13661386template <class _Tp, class _Allocator>
1367_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __sz, const_reference __x) {
1368 size_type __cs = size();
1369 if (__cs < __sz)
1370 this->__append(__sz - __cs, __x);
1371 else if (__cs > __sz)
1372 this->__destruct_at_end(this->__begin_ + __sz);
1387_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __new_size, const_reference __x) {
1388 size_type __current_size = size();
1389 if (__current_size < __new_size) {
1390 if (__new_size <= capacity())
1391 __construct_at_end(__new_size - __current_size, __x);
1392 else {
1393 __split_buffer<value_type, allocator_type> __v(__recommend(__new_size), __current_size, __alloc_);
1394 __v.__construct_at_end(__new_size - __current_size, __x);
1395 __swap_out_circular_buffer(__v);
1396 }
1397 } else if (__current_size > __new_size) {
1398 this->__destruct_at_end(this->__begin_ + __new_size);
1399 }
13731400}
13741401
13751402template <class _Tp, class _Allocator>
lib/libcxx/include/__vector/vector_bool.h+76-83
......@@ -11,6 +11,7 @@
1111
1212#include <__algorithm/copy.h>
1313#include <__algorithm/copy_backward.h>
14#include <__algorithm/copy_n.h>
1415#include <__algorithm/fill_n.h>
1516#include <__algorithm/iterator_operations.h>
1617#include <__algorithm/max.h>
......@@ -19,7 +20,7 @@
1920#include <__bit_reference>
2021#include <__config>
2122#include <__functional/unary_function.h>
22#include <__fwd/bit_reference.h> // TODO: This is a workaround for https://github.com/llvm/llvm-project/issues/131814
23#include <__fwd/bit_reference.h> // TODO: This is a workaround for https://llvm.org/PR131814
2324#include <__fwd/functional.h>
2425#include <__fwd/vector.h>
2526#include <__iterator/distance.h>
......@@ -234,74 +235,89 @@ public:
234235 }
235236#endif
236237
237 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT {
238 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT {
238239 return allocator_type(this->__alloc_);
239240 }
240241
241 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT;
242 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT {
242 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT;
243 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT {
243244 return __internal_cap_to_external(__cap_);
244245 }
245 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT { return __size_; }
246 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT {
247 return __size_;
248 }
246249 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool empty() const _NOEXCEPT {
247250 return __size_ == 0;
248251 }
249252 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reserve(size_type __n);
250253 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void shrink_to_fit() _NOEXCEPT;
251254
252 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() _NOEXCEPT { return __make_iter(0); }
253 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator begin() const _NOEXCEPT { return __make_iter(0); }
254 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() _NOEXCEPT { return __make_iter(__size_); }
255 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator end() const _NOEXCEPT {
255 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() _NOEXCEPT {
256 return __make_iter(0);
257 }
258 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator begin() const _NOEXCEPT {
259 return __make_iter(0);
260 }
261 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() _NOEXCEPT {
262 return __make_iter(__size_);
263 }
264 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator end() const _NOEXCEPT {
256265 return __make_iter(__size_);
257266 }
258267
259 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rbegin() _NOEXCEPT {
268 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rbegin() _NOEXCEPT {
260269 return reverse_iterator(end());
261270 }
262 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rbegin() const _NOEXCEPT {
271 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator
272 rbegin() const _NOEXCEPT {
263273 return const_reverse_iterator(end());
264274 }
265 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rend() _NOEXCEPT {
275 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rend() _NOEXCEPT {
266276 return reverse_iterator(begin());
267277 }
268 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rend() const _NOEXCEPT {
278 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rend() const _NOEXCEPT {
269279 return const_reverse_iterator(begin());
270280 }
271281
272 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cbegin() const _NOEXCEPT { return __make_iter(0); }
273 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cend() const _NOEXCEPT {
282 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cbegin() const _NOEXCEPT {
283 return __make_iter(0);
284 }
285 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cend() const _NOEXCEPT {
274286 return __make_iter(__size_);
275287 }
276 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crbegin() const _NOEXCEPT {
288 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator
289 crbegin() const _NOEXCEPT {
277290 return rbegin();
278291 }
279 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
292 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT {
293 return rend();
294 }
280295
281 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __n) {
296 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __n) {
282297 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector<bool>::operator[] index out of bounds");
283298 return __make_ref(__n);
284299 }
285 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __n) const {
300 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference
301 operator[](size_type __n) const {
286302 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector<bool>::operator[] index out of bounds");
287303 return __make_ref(__n);
288304 }
289 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n);
290 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const;
305 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n);
306 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const;
291307
292 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() {
308 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() {
293309 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::front() called on an empty vector");
294310 return __make_ref(0);
295311 }
296 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const {
312 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const {
297313 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::front() called on an empty vector");
298314 return __make_ref(0);
299315 }
300 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() {
316 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() {
301317 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::back() called on an empty vector");
302318 return __make_ref(__size_ - 1);
303319 }
304 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const {
320 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const {
305321 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::back() called on an empty vector");
306322 return __make_ref(__size_ - 1);
307323 }
......@@ -463,7 +479,6 @@ private:
463479 return (__new_size + (__bits_per_word - 1)) & ~((size_type)__bits_per_word - 1);
464480 }
465481 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __new_size) const;
466 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_at_end(size_type __n, bool __x);
467482 template <class _InputIterator, class _Sentinel>
468483 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
469484 __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n);
......@@ -552,20 +567,6 @@ vector<bool, _Allocator>::__recommend(size_type __new_size) const {
552567 return std::max<size_type>(2 * __cap, __align_it(__new_size));
553568}
554569
555// Default constructs __n objects starting at __end_
556// Precondition: size() + __n <= capacity()
557// Postcondition: size() == size() + __n
558template <class _Allocator>
559inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
560vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x) {
561 _LIBCPP_ASSERT_INTERNAL(
562 capacity() >= size() + __n, "vector<bool>::__construct_at_end called with insufficient capacity");
563 std::fill_n(end(), __n, __x);
564 this->__size_ += __n;
565 if (end().__ctz_ != 0) // Ensure uninitialized leading bits in the last word are set to zero
566 std::fill_n(end(), __bits_per_word - end().__ctz_, 0);
567}
568
569570template <class _Allocator>
570571template <class _InputIterator, class _Sentinel>
571572_LIBCPP_CONSTEXPR_SINCE_CXX20 void
......@@ -598,7 +599,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(size_type __n)
598599 : __begin_(nullptr), __size_(0), __cap_(0) {
599600 if (__n > 0) {
600601 __vallocate(__n);
601 __construct_at_end(__n, false);
602 std::fill_n(__begin_, __external_cap_to_internal(__n), __storage_type(0));
603 __size_ = __n;
602604 }
603605}
604606
......@@ -608,7 +610,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(size_type __n, co
608610 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator>(__a)) {
609611 if (__n > 0) {
610612 __vallocate(__n);
611 __construct_at_end(__n, false);
613 std::fill_n(__begin_, __external_cap_to_internal(__n), __storage_type(0));
614 __size_ = __n;
612615 }
613616}
614617#endif
......@@ -618,7 +621,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(size_type __n, co
618621 : __begin_(nullptr), __size_(0), __cap_(0) {
619622 if (__n > 0) {
620623 __vallocate(__n);
621 __construct_at_end(__n, __x);
624 std::fill_n(__begin_, __external_cap_to_internal(__n), __storage_type(0) - __x);
625 __size_ = __n;
622626 }
623627}
624628
......@@ -628,7 +632,8 @@ vector<bool, _Allocator>::vector(size_type __n, const value_type& __x, const all
628632 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator>(__a)) {
629633 if (__n > 0) {
630634 __vallocate(__n);
631 __construct_at_end(__n, __x);
635 std::fill_n(__begin_, __external_cap_to_internal(__n), __storage_type(0) - __x);
636 __size_ = __n;
632637 }
633638}
634639
......@@ -697,7 +702,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(const vector& __v
697702 __alloc_(__storage_traits::select_on_container_copy_construction(__v.__alloc_)) {
698703 if (__v.size() > 0) {
699704 __vallocate(__v.size());
700 __construct_at_end(__v.begin(), __v.end(), __v.size());
705 std::copy_n(__v.__begin_, __external_cap_to_internal(__v.size()), __begin_);
706 __size_ = __v.size();
701707 }
702708}
703709
......@@ -706,7 +712,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(const vector& __v
706712 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(__a) {
707713 if (__v.size() > 0) {
708714 __vallocate(__v.size());
709 __construct_at_end(__v.begin(), __v.end(), __v.size());
715 std::copy_n(__v.__begin_, __external_cap_to_internal(__v.size()), __begin_);
716 __size_ = __v.size();
710717 }
711718}
712719
......@@ -719,7 +726,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>& vector<bool, _Allocator>
719726 __vdeallocate();
720727 __vallocate(__v.__size_);
721728 }
722 std::copy(__v.__begin_, __v.__begin_ + __external_cap_to_internal(__v.__size_), __begin_);
729 std::copy_n(__v.__begin_, __external_cap_to_internal(__v.size()), __begin_);
723730 }
724731 __size_ = __v.__size_;
725732 }
......@@ -754,7 +761,8 @@ vector<bool, _Allocator>::vector(vector&& __v, const __type_identity_t<allocator
754761 __v.__cap_ = __v.__size_ = 0;
755762 } else if (__v.size() > 0) {
756763 __vallocate(__v.size());
757 __construct_at_end(__v.begin(), __v.end(), __v.size());
764 __size_ = __v.__size_;
765 std::copy_n(__v.__begin_, __external_cap_to_internal(__v.size()), __begin_);
758766 }
759767}
760768
......@@ -849,7 +857,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::reserve(size_type _
849857 this->__throw_length_error();
850858 vector __v(this->get_allocator());
851859 __v.__vallocate(__n);
852 __v.__construct_at_end(this->begin(), this->end(), this->size());
860 __v.__size_ = __size_;
861 std::copy_n(__begin_, __external_cap_to_internal(__size_), __v.__begin_);
853862 swap(__v);
854863 }
855864}
......@@ -956,21 +965,14 @@ vector<bool, _Allocator>::__insert_with_sentinel(const_iterator __position, _Inp
956965 }
957966 vector __v(get_allocator());
958967 if (__first != __last) {
959#if _LIBCPP_HAS_EXCEPTIONS
960 try {
961#endif // _LIBCPP_HAS_EXCEPTIONS
962 __v.__assign_with_sentinel(std::move(__first), std::move(__last));
963 difference_type __old_size = static_cast<difference_type>(__old_end - begin());
964 difference_type __old_p = __p - begin();
965 reserve(__recommend(size() + __v.size()));
966 __p = begin() + __old_p;
967 __old_end = begin() + __old_size;
968#if _LIBCPP_HAS_EXCEPTIONS
969 } catch (...) {
970 erase(__old_end, end());
971 throw;
972 }
973#endif // _LIBCPP_HAS_EXCEPTIONS
968 auto __guard = std::__make_exception_guard([&] { erase(__old_end, end()); });
969 __v.__assign_with_sentinel(std::move(__first), std::move(__last));
970 difference_type __old_size = static_cast<difference_type>(__old_end - begin());
971 difference_type __old_p = __p - begin();
972 reserve(__recommend(size() + __v.size()));
973 __p = begin() + __old_p;
974 __old_end = begin() + __old_size;
975 __guard.__complete();
974976 }
975977 __p = std::rotate(__p, __old_end, end());
976978 insert(__p, __v.begin(), __v.end());
......@@ -1048,25 +1050,16 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::swap(vector& __x)
10481050}
10491051
10501052template <class _Allocator>
1051_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::resize(size_type __sz, value_type __x) {
1052 size_type __cs = size();
1053 if (__cs < __sz) {
1054 iterator __r;
1055 size_type __c = capacity();
1056 size_type __n = __sz - __cs;
1057 if (__n <= __c && __cs <= __c - __n) {
1058 __r = end();
1059 __size_ += __n;
1060 } else {
1061 vector __v(get_allocator());
1062 __v.reserve(__recommend(__size_ + __n));
1063 __v.__size_ = __size_ + __n;
1064 __r = std::copy(cbegin(), cend(), __v.begin());
1065 swap(__v);
1066 }
1067 std::fill_n(__r, __n, __x);
1068 } else
1069 __size_ = __sz;
1053_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::resize(size_type __new_size, value_type __x) {
1054 size_type __current_size = size();
1055 if (__new_size < __current_size) {
1056 __size_ = __new_size;
1057 return;
1058 }
1059
1060 reserve(__new_size);
1061 std::fill_n(end(), __new_size - __current_size, __x);
1062 __size_ = __new_size;
10701063}
10711064
10721065template <class _Allocator>
lib/libcxx/include/any+118-155
......@@ -84,14 +84,12 @@ namespace std {
8484# include <__cxx03/__config>
8585#else
8686# include <__config>
87# include <__memory/allocator.h>
88# include <__memory/allocator_destructor.h>
89# include <__memory/allocator_traits.h>
90# include <__memory/unique_ptr.h>
87# include <__memory/construct_at.h>
88# include <__new/allocate.h>
9189# include <__type_traits/add_cv_quals.h>
9290# include <__type_traits/add_pointer.h>
93# include <__type_traits/aligned_storage.h>
9491# include <__type_traits/conditional.h>
92# include <__type_traits/conjunction.h>
9593# include <__type_traits/decay.h>
9694# include <__type_traits/enable_if.h>
9795# include <__type_traits/is_constructible.h>
......@@ -100,9 +98,11 @@ namespace std {
10098# include <__type_traits/is_reference.h>
10199# include <__type_traits/is_same.h>
102100# include <__type_traits/is_void.h>
101# include <__type_traits/negation.h>
103102# include <__type_traits/remove_cv.h>
104103# include <__type_traits/remove_cvref.h>
105104# include <__type_traits/remove_reference.h>
105# include <__utility/exception_guard.h>
106106# include <__utility/forward.h>
107107# include <__utility/in_place.h>
108108# include <__utility/move.h>
......@@ -142,21 +142,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD
142142class any;
143143
144144template <class _ValueType>
145_LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) _NOEXCEPT;
145_LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) noexcept;
146146
147147template <class _ValueType>
148_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any*) _NOEXCEPT;
148_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any*) noexcept;
149149
150150namespace __any_imp {
151_LIBCPP_SUPPRESS_DEPRECATED_PUSH
152using _Buffer _LIBCPP_NODEBUG = aligned_storage_t<3 * sizeof(void*), alignof(void*)>;
153_LIBCPP_SUPPRESS_DEPRECATED_POP
151inline constexpr size_t __small_buffer_size = 3 * sizeof(void*);
152inline constexpr size_t __small_buffer_alignment = alignof(void*);
154153
155154template <class _Tp>
156155using _IsSmallObject _LIBCPP_NODEBUG =
157156 integral_constant<bool,
158 sizeof(_Tp) <= sizeof(_Buffer) && alignof(_Buffer) % alignof(_Tp) == 0 &&
159 is_nothrow_move_constructible<_Tp>::value >;
157 sizeof(_Tp) <= __small_buffer_size && alignof(_Tp) <= __small_buffer_alignment &&
158 is_nothrow_move_constructible_v<_Tp>>;
160159
161160enum class _Action { _Destroy, _Copy, _Move, _Get, _TypeInfo };
162161
......@@ -192,37 +191,44 @@ using _Handler _LIBCPP_NODEBUG = conditional_t< _IsSmallObject<_Tp>::value, _Sma
192191class any {
193192public:
194193 // construct/destruct
195 _LIBCPP_HIDE_FROM_ABI constexpr any() _NOEXCEPT : __h_(nullptr) {}
194 _LIBCPP_HIDE_FROM_ABI constexpr any() noexcept : __h_(nullptr) {}
196195
197196 _LIBCPP_HIDE_FROM_ABI any(any const& __other) : __h_(nullptr) {
198197 if (__other.__h_)
199198 __other.__call(_Action::_Copy, this);
200199 }
201200
202 _LIBCPP_HIDE_FROM_ABI any(any&& __other) _NOEXCEPT : __h_(nullptr) {
201 _LIBCPP_HIDE_FROM_ABI any(any&& __other) noexcept : __h_(nullptr) {
203202 if (__other.__h_)
204203 __other.__call(_Action::_Move, this);
205204 }
206205
207 template < class _ValueType,
208 class _Tp = decay_t<_ValueType>,
209 class = enable_if_t< !is_same<_Tp, any>::value && !__is_inplace_type<_ValueType>::value &&
210 is_copy_constructible<_Tp>::value> >
211 _LIBCPP_HIDE_FROM_ABI any(_ValueType&& __value);
206 template <
207 class _ValueType,
208 class _Tp = decay_t<_ValueType>,
209 enable_if_t<_And<_Not<is_same<_Tp, any>>, _Not<__is_inplace_type<_ValueType>>, is_copy_constructible<_Tp>>::value,
210 int> = 0>
211 _LIBCPP_HIDE_FROM_ABI any(_ValueType&& __value) : __h_(nullptr) {
212 __any_imp::_Handler<_Tp>::__create(*this, std::forward<_ValueType>(__value));
213 }
212214
213215 template <class _ValueType,
214216 class... _Args,
215 class _Tp = decay_t<_ValueType>,
216 class = enable_if_t< is_constructible<_Tp, _Args...>::value && is_copy_constructible<_Tp>::value > >
217 _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, _Args&&... __args);
217 class _Tp = decay_t<_ValueType>,
218 enable_if_t<is_constructible_v<_Tp, _Args...> && is_copy_constructible_v<_Tp>, int> = 0>
219 _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, _Args&&... __args) {
220 __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...);
221 }
218222
219 template <class _ValueType,
220 class _Up,
221 class... _Args,
222 class _Tp = decay_t<_ValueType>,
223 class = enable_if_t< is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
224 is_copy_constructible<_Tp>::value> >
225 _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);
223 template <
224 class _ValueType,
225 class _Up,
226 class... _Args,
227 class _Tp = decay_t<_ValueType>,
228 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...> && is_copy_constructible_v<_Tp>, int> = 0>
229 _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
230 __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...);
231 }
226232
227233 _LIBCPP_HIDE_FROM_ABI ~any() { this->reset(); }
228234
......@@ -232,43 +238,65 @@ public:
232238 return *this;
233239 }
234240
235 _LIBCPP_HIDE_FROM_ABI any& operator=(any&& __rhs) _NOEXCEPT {
241 _LIBCPP_HIDE_FROM_ABI any& operator=(any&& __rhs) noexcept {
236242 any(std::move(__rhs)).swap(*this);
237243 return *this;
238244 }
239245
240 template < class _ValueType,
241 class _Tp = decay_t<_ValueType>,
242 class = enable_if_t< !is_same<_Tp, any>::value && is_copy_constructible<_Tp>::value> >
243 _LIBCPP_HIDE_FROM_ABI any& operator=(_ValueType&& __rhs);
244
245246 template <class _ValueType,
246 class... _Args,
247 class _Tp = decay_t<_ValueType>,
248 class = enable_if_t< is_constructible<_Tp, _Args...>::value && is_copy_constructible<_Tp>::value> >
249 _LIBCPP_HIDE_FROM_ABI _Tp& emplace(_Args&&...);
247 class _Tp = decay_t<_ValueType>,
248 enable_if_t<!is_same_v<_Tp, any> && is_copy_constructible_v<_Tp>, int> = 0>
249 _LIBCPP_HIDE_FROM_ABI any& operator=(_ValueType&& __rhs) {
250 any(std::forward<_ValueType>(__rhs)).swap(*this);
251 return *this;
252 }
250253
251254 template <class _ValueType,
252 class _Up,
253255 class... _Args,
254 class _Tp = decay_t<_ValueType>,
255 class = enable_if_t< is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
256 is_copy_constructible<_Tp>::value> >
257 _LIBCPP_HIDE_FROM_ABI _Tp& emplace(initializer_list<_Up>, _Args&&...);
256 class _Tp = decay_t<_ValueType>,
257 enable_if_t<is_constructible_v<_Tp, _Args...> && is_copy_constructible_v<_Tp>, int> = 0>
258 _LIBCPP_HIDE_FROM_ABI _Tp& emplace(_Args&&... __args) {
259 reset();
260 return __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...);
261 }
262
263 template <
264 class _ValueType,
265 class _Up,
266 class... _Args,
267 class _Tp = decay_t<_ValueType>,
268 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...> && is_copy_constructible_v<_Tp>, int> = 0>
269 _LIBCPP_HIDE_FROM_ABI _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
270 reset();
271 return __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...);
272 }
258273
259274 // 6.3.3 any modifiers
260 _LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT {
275 _LIBCPP_HIDE_FROM_ABI void reset() noexcept {
261276 if (__h_)
262277 this->__call(_Action::_Destroy);
263278 }
264279
265 _LIBCPP_HIDE_FROM_ABI void swap(any& __rhs) _NOEXCEPT;
280 _LIBCPP_HIDE_FROM_ABI void swap(any& __rhs) noexcept {
281 if (this == &__rhs)
282 return;
283 if (__h_ && __rhs.__h_) {
284 any __tmp;
285 __rhs.__call(_Action::_Move, &__tmp);
286 this->__call(_Action::_Move, &__rhs);
287 __tmp.__call(_Action::_Move, this);
288 } else if (__h_) {
289 this->__call(_Action::_Move, &__rhs);
290 } else if (__rhs.__h_) {
291 __rhs.__call(_Action::_Move, this);
292 }
293 }
266294
267295 // 6.3.4 any observers
268 _LIBCPP_HIDE_FROM_ABI bool has_value() const _NOEXCEPT { return __h_ != nullptr; }
296 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool has_value() const noexcept { return __h_ != nullptr; }
269297
270298# if _LIBCPP_HAS_RTTI
271 _LIBCPP_HIDE_FROM_ABI const type_info& type() const _NOEXCEPT {
299 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const type_info& type() const noexcept {
272300 if (__h_) {
273301 return *static_cast<type_info const*>(this->__call(_Action::_TypeInfo));
274302 } else {
......@@ -285,7 +313,7 @@ private:
285313 union _Storage {
286314 _LIBCPP_HIDE_FROM_ABI constexpr _Storage() : __ptr(nullptr) {}
287315 void* __ptr;
288 __any_imp::_Buffer __buf;
316 alignas(__any_imp::__small_buffer_alignment) char __buf[__any_imp::__small_buffer_size];
289317 };
290318
291319 _LIBCPP_HIDE_FROM_ABI void*
......@@ -305,10 +333,10 @@ private:
305333 friend struct __any_imp::_LargeHandler;
306334
307335 template <class _ValueType>
308 friend add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) _NOEXCEPT;
336 friend add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) noexcept;
309337
310338 template <class _ValueType>
311 friend add_pointer_t<_ValueType> any_cast(any*) _NOEXCEPT;
339 friend add_pointer_t<_ValueType> any_cast(any*) noexcept;
312340
313341 _HandleFuncPtr __h_ = nullptr;
314342 _Storage __s_;
......@@ -339,22 +367,14 @@ struct _SmallHandler {
339367
340368 template <class... _Args>
341369 _LIBCPP_HIDE_FROM_ABI static _Tp& __create(any& __dest, _Args&&... __args) {
342 typedef allocator<_Tp> _Alloc;
343 typedef allocator_traits<_Alloc> _ATraits;
344 _Alloc __a;
345 _Tp* __ret = static_cast<_Tp*>(static_cast<void*>(&__dest.__s_.__buf));
346 _ATraits::construct(__a, __ret, std::forward<_Args>(__args)...);
370 auto __ret = std::__construct_at(reinterpret_cast<_Tp*>(&__dest.__s_.__buf), std::forward<_Args>(__args)...);
347371 __dest.__h_ = &_SmallHandler::__handle;
348372 return *__ret;
349373 }
350374
351375private:
352376 _LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) {
353 typedef allocator<_Tp> _Alloc;
354 typedef allocator_traits<_Alloc> _ATraits;
355 _Alloc __a;
356 _Tp* __p = static_cast<_Tp*>(static_cast<void*>(&__this.__s_.__buf));
357 _ATraits::destroy(__a, __p);
377 std::__destroy_at(reinterpret_cast<_Tp*>(&__this.__s_.__buf));
358378 __this.__h_ = nullptr;
359379 }
360380
......@@ -406,26 +426,20 @@ struct _LargeHandler {
406426
407427 template <class... _Args>
408428 _LIBCPP_HIDE_FROM_ABI static _Tp& __create(any& __dest, _Args&&... __args) {
409 typedef allocator<_Tp> _Alloc;
410 typedef allocator_traits<_Alloc> _ATraits;
411 typedef __allocator_destructor<_Alloc> _Dp;
412 _Alloc __a;
413 unique_ptr<_Tp, _Dp> __hold(_ATraits::allocate(__a, 1), _Dp(__a, 1));
414 _Tp* __ret = __hold.get();
415 _ATraits::construct(__a, __ret, std::forward<_Args>(__args)...);
416 __dest.__s_.__ptr = __hold.release();
429 _Tp* __ptr = static_cast<_Tp*>(std::__libcpp_allocate<_Tp>(__element_count(1)));
430 std::__exception_guard __guard([&] { std::__libcpp_deallocate<_Tp>(__ptr, __element_count(1)); });
431 std::__construct_at(__ptr, std::forward<_Args>(__args)...);
432 __guard.__complete();
433 __dest.__s_.__ptr = __ptr;
417434 __dest.__h_ = &_LargeHandler::__handle;
418 return *__ret;
435 return *__ptr;
419436 }
420437
421438private:
422439 _LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) {
423 typedef allocator<_Tp> _Alloc;
424 typedef allocator_traits<_Alloc> _ATraits;
425 _Alloc __a;
426440 _Tp* __p = static_cast<_Tp*>(__this.__s_.__ptr);
427 _ATraits::destroy(__a, __p);
428 _ATraits::deallocate(__a, __p, 1);
441 std::__destroy_at(__p);
442 std::__libcpp_deallocate<_Tp>(__p, __element_count(1));
429443 __this.__h_ = nullptr;
430444 }
431445
......@@ -456,72 +470,24 @@ private:
456470
457471} // namespace __any_imp
458472
459template <class _ValueType, class _Tp, class>
460any::any(_ValueType&& __v) : __h_(nullptr) {
461 __any_imp::_Handler<_Tp>::__create(*this, std::forward<_ValueType>(__v));
462}
463
464template <class _ValueType, class... _Args, class _Tp, class>
465any::any(in_place_type_t<_ValueType>, _Args&&... __args) {
466 __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...);
467}
468
469template <class _ValueType, class _Up, class... _Args, class _Tp, class>
470any::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
471 __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...);
472}
473
474template <class _ValueType, class, class>
475inline _LIBCPP_HIDE_FROM_ABI any& any::operator=(_ValueType&& __v) {
476 any(std::forward<_ValueType>(__v)).swap(*this);
477 return *this;
478}
479
480template <class _ValueType, class... _Args, class _Tp, class>
481inline _LIBCPP_HIDE_FROM_ABI _Tp& any::emplace(_Args&&... __args) {
482 reset();
483 return __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...);
484}
485
486template <class _ValueType, class _Up, class... _Args, class _Tp, class>
487inline _LIBCPP_HIDE_FROM_ABI _Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
488 reset();
489 return __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...);
490}
491
492inline _LIBCPP_HIDE_FROM_ABI void any::swap(any& __rhs) _NOEXCEPT {
493 if (this == &__rhs)
494 return;
495 if (__h_ && __rhs.__h_) {
496 any __tmp;
497 __rhs.__call(_Action::_Move, &__tmp);
498 this->__call(_Action::_Move, &__rhs);
499 __tmp.__call(_Action::_Move, this);
500 } else if (__h_) {
501 this->__call(_Action::_Move, &__rhs);
502 } else if (__rhs.__h_) {
503 __rhs.__call(_Action::_Move, this);
504 }
505}
506
507473// 6.4 Non-member functions
508474
509inline _LIBCPP_HIDE_FROM_ABI void swap(any& __lhs, any& __rhs) _NOEXCEPT { __lhs.swap(__rhs); }
475inline _LIBCPP_HIDE_FROM_ABI void swap(any& __lhs, any& __rhs) noexcept { __lhs.swap(__rhs); }
510476
511477template <class _Tp, class... _Args>
512inline _LIBCPP_HIDE_FROM_ABI any make_any(_Args&&... __args) {
478[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI any make_any(_Args&&... __args) {
513479 return any(in_place_type<_Tp>, std::forward<_Args>(__args)...);
514480}
515481
516482template <class _Tp, class _Up, class... _Args>
517inline _LIBCPP_HIDE_FROM_ABI any make_any(initializer_list<_Up> __il, _Args&&... __args) {
483[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI any make_any(initializer_list<_Up> __il, _Args&&... __args) {
518484 return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...);
519485}
520486
521487template <class _ValueType>
522inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any const& __v) {
488[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any const& __v) {
523489 using _RawValueType = __remove_cvref_t<_ValueType>;
524 static_assert(is_constructible<_ValueType, _RawValueType const&>::value,
490 static_assert(is_constructible_v<_ValueType, _RawValueType const&>,
525491 "ValueType is required to be a const lvalue reference "
526492 "or a CopyConstructible type");
527493 auto __tmp = std::any_cast<add_const_t<_RawValueType>>(&__v);
......@@ -531,9 +497,9 @@ inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any const& __v) {
531497}
532498
533499template <class _ValueType>
534inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any& __v) {
500[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any& __v) {
535501 using _RawValueType = __remove_cvref_t<_ValueType>;
536 static_assert(is_constructible<_ValueType, _RawValueType&>::value,
502 static_assert(is_constructible_v<_ValueType, _RawValueType&>,
537503 "ValueType is required to be an lvalue reference "
538504 "or a CopyConstructible type");
539505 auto __tmp = std::any_cast<_RawValueType>(&__v);
......@@ -543,9 +509,9 @@ inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any& __v) {
543509}
544510
545511template <class _ValueType>
546inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any&& __v) {
512[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any&& __v) {
547513 using _RawValueType = __remove_cvref_t<_ValueType>;
548 static_assert(is_constructible<_ValueType, _RawValueType>::value,
514 static_assert(is_constructible_v<_ValueType, _RawValueType>,
549515 "ValueType is required to be an rvalue reference "
550516 "or a CopyConstructible type");
551517 auto __tmp = std::any_cast<_RawValueType>(&__v);
......@@ -555,39 +521,31 @@ inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any&& __v) {
555521}
556522
557523template <class _ValueType>
558inline _LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const* __any) _NOEXCEPT {
524[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const* __any) noexcept {
559525 static_assert(!is_void_v<_ValueType>, "_ValueType may not be void.");
560 static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference.");
526 static_assert(!is_reference_v<_ValueType>, "_ValueType may not be a reference.");
561527 return std::any_cast<_ValueType>(const_cast<any*>(__any));
562528}
563529
564template <class _RetType>
565inline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void* __p, /*IsFunction*/ false_type) noexcept {
566 return static_cast<_RetType>(__p);
567}
568
569template <class _RetType>
570inline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void*, /*IsFunction*/ true_type) noexcept {
571 return nullptr;
572}
573
574530template <class _ValueType>
575_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any* __any) _NOEXCEPT {
531[[nodiscard]] _LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any* __any) noexcept {
576532 using __any_imp::_Action;
577533 static_assert(!is_void_v<_ValueType>, "_ValueType may not be void.");
578 static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference.");
579 typedef add_pointer_t<_ValueType> _ReturnType;
580 if (__any && __any->__h_) {
581 void* __p = __any->__call(
582 _Action::_Get,
583 nullptr,
534 static_assert(!is_reference_v<_ValueType>, "_ValueType may not be a reference.");
535 if constexpr (!is_function_v<_ValueType>) {
536 using _ReturnType = add_pointer_t<_ValueType>;
537 if (__any && __any->__h_) {
538 void* __p = __any->__call(
539 _Action::_Get,
540 nullptr,
584541# if _LIBCPP_HAS_RTTI
585 &typeid(_ValueType),
542 &typeid(_ValueType),
586543# else
587 nullptr,
544 nullptr,
588545# endif
589 __any_imp::__get_fallback_typeid<_ValueType>());
590 return std::__pointer_or_func_cast<_ReturnType>(__p, is_function<_ValueType>{});
546 __any_imp::__get_fallback_typeid<_ValueType>());
547 return static_cast<_ReturnType>(__p);
548 }
591549 }
592550 return nullptr;
593551}
......@@ -613,6 +571,11 @@ _LIBCPP_POP_MACROS
613571# include <type_traits>
614572# include <variant>
615573# endif
574
575# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23
576# include <cstring>
577# include <limits>
578# endif
616579#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
617580
618581#endif // _LIBCPP_ANY
lib/libcxx/include/array+88-56
......@@ -134,7 +134,6 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
134134# include <__type_traits/is_const.h>
135135# include <__type_traits/is_constructible.h>
136136# include <__type_traits/is_nothrow_constructible.h>
137# include <__type_traits/is_replaceable.h>
138137# include <__type_traits/is_same.h>
139138# include <__type_traits/is_swappable.h>
140139# include <__type_traits/is_trivially_relocatable.h>
......@@ -176,7 +175,6 @@ template <class _Tp, size_t _Size>
176175struct array {
177176 using __trivially_relocatable _LIBCPP_NODEBUG =
178177 __conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, array, void>;
179 using __replaceable _LIBCPP_NODEBUG = __conditional_t<__is_replaceable_v<_Tp>, array, void>;
180178
181179 // types:
182180 using __self _LIBCPP_NODEBUG = array;
......@@ -212,28 +210,28 @@ struct array {
212210 }
213211
214212 // iterators:
215 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT {
213 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT {
216214# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
217215 return std::__make_static_bounded_iter<_Size>(data(), data());
218216# else
219217 return iterator(data());
220218# endif
221219 }
222 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT {
220 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT {
223221# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
224222 return std::__make_static_bounded_iter<_Size>(data(), data());
225223# else
226224 return const_iterator(data());
227225# endif
228226 }
229 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT {
227 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT {
230228# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
231229 return std::__make_static_bounded_iter<_Size>(data() + _Size, data());
232230# else
233231 return iterator(data() + _Size);
234232# endif
235233 }
236 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT {
234 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT {
237235# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
238236 return std::__make_static_bounded_iter<_Size>(data() + _Size, data());
239237# else
......@@ -241,62 +239,81 @@ struct array {
241239# endif
242240 }
243241
244 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT {
242 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT {
245243 return reverse_iterator(end());
246244 }
247 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT {
245 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator
246 rbegin() const _NOEXCEPT {
248247 return const_reverse_iterator(end());
249248 }
250 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT {
249 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT {
251250 return reverse_iterator(begin());
252251 }
253 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT {
252 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT {
254253 return const_reverse_iterator(begin());
255254 }
256255
257 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { return begin(); }
258 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { return end(); }
259 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT {
256 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT {
257 return begin();
258 }
259 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT {
260 return end();
261 }
262 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator
263 crbegin() const _NOEXCEPT {
260264 return rbegin();
261265 }
262 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
266 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT {
267 return rend();
268 }
263269
264270 // capacity:
265 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return _Size; }
266 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return _Size; }
271 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return _Size; }
272 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return _Size; }
267273 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return _Size == 0; }
268274
269275 // element access:
270 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type __n) _NOEXCEPT {
276 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type __n) _NOEXCEPT {
271277 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
272278 return __elems_[__n];
273279 }
274 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type __n) const _NOEXCEPT {
280 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference
281 operator[](size_type __n) const _NOEXCEPT {
275282 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
276283 return __elems_[__n];
277284 }
278285
279 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n) {
286 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n) {
280287 if (__n >= _Size)
281288 std::__throw_out_of_range("array::at");
282289 return __elems_[__n];
283290 }
284291
285 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const {
292 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const {
286293 if (__n >= _Size)
287294 std::__throw_out_of_range("array::at");
288295 return __elems_[__n];
289296 }
290297
291 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { return (*this)[0]; }
292 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { return (*this)[0]; }
293 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { return (*this)[_Size - 1]; }
294 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT {
298 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT {
299 return (*this)[0];
300 }
301 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT {
302 return (*this)[0];
303 }
304 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT {
305 return (*this)[_Size - 1];
306 }
307 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT {
295308 return (*this)[_Size - 1];
296309 }
297310
298 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return __elems_; }
299 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { return __elems_; }
311 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT {
312 return __elems_;
313 }
314 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT {
315 return __elems_;
316 }
300317};
301318
302319template <class _Tp>
......@@ -330,8 +347,10 @@ struct array<_Tp, 0> {
330347 };
331348 _ALIGNAS_TYPE(_ArrayInStructT) _EmptyType __elems_[sizeof(_ArrayInStructT)];
332349
333 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return nullptr; }
334 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { return nullptr; }
350 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return nullptr; }
351 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT {
352 return nullptr;
353 }
335354
336355 // No explicit construct/copy/destroy for aggregate type
337356 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void fill(const value_type&) {
......@@ -343,28 +362,28 @@ struct array<_Tp, 0> {
343362 }
344363
345364 // iterators:
346 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT {
365 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT {
347366# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
348367 return std::__make_static_bounded_iter<0>(data(), data());
349368# else
350369 return iterator(data());
351370# endif
352371 }
353 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT {
372 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT {
354373# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
355374 return std::__make_static_bounded_iter<0>(data(), data());
356375# else
357376 return const_iterator(data());
358377# endif
359378 }
360 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT {
379 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT {
361380# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
362381 return std::__make_static_bounded_iter<0>(data(), data());
363382# else
364383 return iterator(data());
365384# endif
366385 }
367 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT {
386 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT {
368387# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY)
369388 return std::__make_static_bounded_iter<0>(data(), data());
370389# else
......@@ -372,68 +391,77 @@ struct array<_Tp, 0> {
372391# endif
373392 }
374393
375 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT {
394 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT {
376395 return reverse_iterator(end());
377396 }
378 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT {
397 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator
398 rbegin() const _NOEXCEPT {
379399 return const_reverse_iterator(end());
380400 }
381 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT {
401 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT {
382402 return reverse_iterator(begin());
383403 }
384 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT {
404 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT {
385405 return const_reverse_iterator(begin());
386406 }
387407
388 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { return begin(); }
389 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { return end(); }
390 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT {
408 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT {
409 return begin();
410 }
411 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT {
412 return end();
413 }
414 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator
415 crbegin() const _NOEXCEPT {
391416 return rbegin();
392417 }
393 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
418 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT {
419 return rend();
420 }
394421
395422 // capacity:
396 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return 0; }
397 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return 0; }
423 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return 0; }
424 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return 0; }
398425 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return true; }
399426
400427 // element access:
401 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type) _NOEXCEPT {
428 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type) _NOEXCEPT {
402429 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
403430 __libcpp_unreachable();
404431 }
405432
406 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type) const _NOEXCEPT {
433 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference
434 operator[](size_type) const _NOEXCEPT {
407435 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
408436 __libcpp_unreachable();
409437 }
410438
411 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type) {
439 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type) {
412440 std::__throw_out_of_range("array<T, 0>::at");
413441 __libcpp_unreachable();
414442 }
415443
416 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type) const {
444 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type) const {
417445 std::__throw_out_of_range("array<T, 0>::at");
418446 __libcpp_unreachable();
419447 }
420448
421 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT {
449 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT {
422450 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array");
423451 __libcpp_unreachable();
424452 }
425453
426 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT {
454 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT {
427455 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array");
428456 __libcpp_unreachable();
429457 }
430458
431 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT {
459 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT {
432460 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array");
433461 __libcpp_unreachable();
434462 }
435463
436 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT {
464 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT {
437465 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array");
438466 __libcpp_unreachable();
439467 }
......@@ -503,25 +531,29 @@ struct tuple_element<_Ip, array<_Tp, _Size> > {
503531};
504532
505533template <size_t _Ip, class _Tp, size_t _Size>
506inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& get(array<_Tp, _Size>& __a) _NOEXCEPT {
534[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&
535get(array<_Tp, _Size>& __a) _NOEXCEPT {
507536 static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)");
508537 return __a.__elems_[_Ip];
509538}
510539
511540template <size_t _Ip, class _Tp, size_t _Size>
512inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& get(const array<_Tp, _Size>& __a) _NOEXCEPT {
541[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&
542get(const array<_Tp, _Size>& __a) _NOEXCEPT {
513543 static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)");
514544 return __a.__elems_[_Ip];
515545}
516546
517547template <size_t _Ip, class _Tp, size_t _Size>
518inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&& get(array<_Tp, _Size>&& __a) _NOEXCEPT {
548[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&&
549get(array<_Tp, _Size>&& __a) _NOEXCEPT {
519550 static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)");
520551 return std::move(__a.__elems_[_Ip]);
521552}
522553
523554template <size_t _Ip, class _Tp, size_t _Size>
524inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&& get(const array<_Tp, _Size>&& __a) _NOEXCEPT {
555[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&&
556get(const array<_Tp, _Size>&& __a) _NOEXCEPT {
525557 static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array &&)");
526558 return std::move(__a.__elems_[_Ip]);
527559}
......@@ -541,7 +573,7 @@ __to_array_rvalue_impl(_Tp (&&__arr)[_Size], index_sequence<_Index...>) {
541573}
542574
543575template <typename _Tp, size_t _Size>
544_LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size>
576[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size>
545577to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) {
546578 static_assert(!is_array_v<_Tp>, "[array.creation]/1: to_array does not accept multidimensional arrays.");
547579 static_assert(is_constructible_v<_Tp, _Tp&>, "[array.creation]/1: to_array requires copy constructible elements.");
......@@ -549,7 +581,7 @@ to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) {
549581}
550582
551583template <typename _Tp, size_t _Size>
552_LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size>
584[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size>
553585to_array(_Tp (&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) {
554586 static_assert(!is_array_v<_Tp>, "[array.creation]/4: to_array does not accept multidimensional arrays.");
555587 static_assert(is_move_constructible_v<_Tp>, "[array.creation]/4: to_array requires move constructible elements.");
lib/libcxx/include/atomic+2
......@@ -608,6 +608,8 @@ template <class T>
608608# include <__atomic/atomic_init.h>
609609# include <__atomic/atomic_lock_free.h>
610610# include <__atomic/atomic_sync.h>
611# include <__atomic/atomic_sync_timed.h>
612# include <__atomic/atomic_waitable_traits.h>
611613# include <__atomic/check_memory_order.h>
612614# include <__atomic/contention_t.h>
613615# include <__atomic/fence.h>
lib/libcxx/include/barrier+20-24
......@@ -57,8 +57,6 @@ namespace std
5757# include <__atomic/memory_order.h>
5858# include <__cstddef/ptrdiff_t.h>
5959# include <__memory/unique_ptr.h>
60# include <__thread/poll_with_backoff.h>
61# include <__thread/timed_backoff_policy.h>
6260# include <__utility/move.h>
6361# include <cstdint>
6462# include <limits>
......@@ -97,19 +95,20 @@ using __barrier_phase_t _LIBCPP_NODEBUG = uint8_t;
9795
9896class __barrier_algorithm_base;
9997
100_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __barrier_algorithm_base*
101__construct_barrier_algorithm_base(ptrdiff_t& __expected);
98[[__gnu__::__returns_nonnull__, __gnu__::__malloc__]]
99_LIBCPP_EXPORTED_FROM_ABI __barrier_algorithm_base* __construct_barrier_algorithm_base(ptrdiff_t& __expected);
102100
103_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI bool
104__arrive_barrier_algorithm_base(__barrier_algorithm_base* __barrier, __barrier_phase_t __old_phase) noexcept;
101_LIBCPP_EXPORTED_FROM_ABI bool
102__arrive_barrier_algorithm_base([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE __barrier_algorithm_base* __barrier,
103 __barrier_phase_t __old_phase) noexcept;
105104
106_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
107__destroy_barrier_algorithm_base(__barrier_algorithm_base* __barrier) noexcept;
105_LIBCPP_EXPORTED_FROM_ABI void __destroy_barrier_algorithm_base(
106 [[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE __barrier_algorithm_base* __barrier) noexcept;
108107
109108template <class _CompletionF>
110109class __barrier_base {
111110 ptrdiff_t __expected_;
112 unique_ptr<__barrier_algorithm_base, void (*)(__barrier_algorithm_base*)> __base_;
111 unique_ptr<__barrier_algorithm_base, void (*)(_LIBCPP_NOESCAPE __barrier_algorithm_base*)> __base_;
113112 atomic<ptrdiff_t> __expected_adjustment_;
114113 _CompletionF __completion_;
115114 atomic<__barrier_phase_t> __phase_;
......@@ -119,14 +118,13 @@ public:
119118
120119 static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { return numeric_limits<ptrdiff_t>::max(); }
121120
122 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
123 __barrier_base(ptrdiff_t __expected, _CompletionF __completion = _CompletionF())
121 _LIBCPP_HIDE_FROM_ABI __barrier_base(ptrdiff_t __expected, _CompletionF __completion = _CompletionF())
124122 : __expected_(__expected),
125123 __base_(std::__construct_barrier_algorithm_base(this->__expected_), &__destroy_barrier_algorithm_base),
126124 __expected_adjustment_(0),
127125 __completion_(std::move(__completion)),
128126 __phase_(0) {}
129 [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI arrival_token arrive(ptrdiff_t __update) {
127 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI arrival_token arrive(ptrdiff_t __update) {
130128 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
131129 __update <= __expected_, "update is greater than the expected count for the current barrier phase");
132130
......@@ -141,11 +139,10 @@ public:
141139 }
142140 return __old_phase;
143141 }
144 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(arrival_token&& __old_phase) const {
145 auto const __test_fn = [this, __old_phase]() -> bool { return __phase_.load(memory_order_acquire) != __old_phase; };
146 std::__libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
142 _LIBCPP_HIDE_FROM_ABI void wait(arrival_token&& __old_phase) const {
143 __phase_.wait(__old_phase, std::memory_order_acquire);
147144 }
148 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void arrive_and_drop() {
145 _LIBCPP_HIDE_FROM_ABI void arrive_and_drop() {
149146 __expected_adjustment_.fetch_sub(1, memory_order_relaxed);
150147 (void)arrive(1);
151148 }
......@@ -158,9 +155,10 @@ class barrier {
158155public:
159156 using arrival_token = typename __barrier_base<_CompletionF>::arrival_token;
160157
161 static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { return __barrier_base<_CompletionF>::max(); }
158 [[nodiscard]] static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {
159 return __barrier_base<_CompletionF>::max();
160 }
162161
163 _LIBCPP_AVAILABILITY_SYNC
164162 _LIBCPP_HIDE_FROM_ABI explicit barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF())
165163 : __b_(__count, std::move(__completion)) {
166164 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
......@@ -175,15 +173,13 @@ public:
175173 barrier(barrier const&) = delete;
176174 barrier& operator=(barrier const&) = delete;
177175
178 [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI arrival_token arrive(ptrdiff_t __update = 1) {
176 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI arrival_token arrive(ptrdiff_t __update = 1) {
179177 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__update > 0, "barrier:arrive must be called with a value greater than 0");
180178 return __b_.arrive(__update);
181179 }
182 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(arrival_token&& __phase) const {
183 __b_.wait(std::move(__phase));
184 }
185 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void arrive_and_wait() { wait(arrive()); }
186 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void arrive_and_drop() { __b_.arrive_and_drop(); }
180 _LIBCPP_HIDE_FROM_ABI void wait(arrival_token&& __phase) const { __b_.wait(std::move(__phase)); }
181 _LIBCPP_HIDE_FROM_ABI void arrive_and_wait() { wait(arrive()); }
182 _LIBCPP_HIDE_FROM_ABI void arrive_and_drop() { __b_.arrive_and_drop(); }
187183};
188184
189185_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/bitset+49-30
......@@ -147,7 +147,6 @@ template <size_t N> struct hash<std::bitset<N>>;
147147# include <__functional/hash.h>
148148# include <__functional/identity.h>
149149# include <__functional/unary_function.h>
150# include <__tuple/tuple_indices.h>
151150# include <__type_traits/enable_if.h>
152151# include <__type_traits/integral_constant.h>
153152# include <__type_traits/is_char_like_type.h>
......@@ -314,7 +313,7 @@ private:
314313 _LIBCPP_HIDE_FROM_ABI void __init(unsigned long long __v, true_type) _NOEXCEPT;
315314# else
316315 template <size_t... _Indices>
317 _LIBCPP_HIDE_FROM_ABI constexpr __bitset(unsigned long long __v, std::__tuple_indices<_Indices...>) _NOEXCEPT
316 _LIBCPP_HIDE_FROM_ABI constexpr __bitset(unsigned long long __v, __index_sequence<_Indices...>) _NOEXCEPT
318317 : __first_{static_cast<__storage_type>(__v >> (_Indices * __bits_per_word))...} {}
319318# endif // _LIBCPP_CXX03_LANG
320319};
......@@ -352,10 +351,9 @@ template <size_t _N_words, size_t _Size>
352351inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
353352# ifndef _LIBCPP_CXX03_LANG
354353 : __bitset(__v,
355 std::__make_indices_imp< (_N_words < (sizeof(unsigned long long) - 1) / sizeof(__storage_type) + 1)
356 ? _N_words
357 : (sizeof(unsigned long long) - 1) / sizeof(__storage_type) + 1,
358 0>{})
354 __make_index_sequence<(_N_words < (sizeof(unsigned long long) - 1) / sizeof(__storage_type) + 1)
355 ? _N_words
356 : (sizeof(unsigned long long) - 1) / sizeof(__storage_type) + 1>())
359357# endif
360358{
361359# ifdef _LIBCPP_CXX03_LANG
......@@ -677,53 +675,63 @@ public:
677675 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& set(size_t __pos, bool __val = true);
678676 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& reset() _NOEXCEPT;
679677 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& reset(size_t __pos);
680 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator~() const _NOEXCEPT;
678 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator~() const _NOEXCEPT;
681679 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& flip() _NOEXCEPT;
682680 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& flip(size_t __pos);
683681
684682 // element access:
685# ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
686 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const {
683 // TODO(LLVM 24): Remove the opt-out
684# ifndef _LIBCPP_DEPRECATED_ABI_BITSET_CONST_SUBSCRIPT_RETURN_REF
685 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const {
687686 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds");
688687 return __base::__make_ref(__p);
689688 }
690689# else
691 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference operator[](size_t __p) const {
690 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference operator[](size_t __p) const {
692691 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds");
693692 return __base::__make_ref(__p);
694693 }
695694# endif
696 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference operator[](size_t __p) {
695 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference operator[](size_t __p) {
697696 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds");
698697 return __base::__make_ref(__p);
699698 }
700 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return __base::to_ulong(); }
701 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const {
699 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const {
700 return __base::to_ulong();
701 }
702 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const {
702703 return __base::to_ullong();
703704 }
704705 template <class _CharT, class _Traits, class _Allocator>
705 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator>
706 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator>
706707 to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const;
707708 template <class _CharT, class _Traits>
708 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, allocator<_CharT> >
709 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
710 _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, allocator<_CharT> >
709711 to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const;
710712 template <class _CharT>
711 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> >
713 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
714 _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> >
712715 to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const;
713 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<char, char_traits<char>, allocator<char> >
716 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
717 _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<char, char_traits<char>, allocator<char> >
714718 to_string(char __zero = '0', char __one = '1') const;
715 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 size_t count() const _NOEXCEPT;
716 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT { return _Size; }
719 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 size_t count() const _NOEXCEPT;
720 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT { return _Size; }
717721 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const bitset& __rhs) const _NOEXCEPT;
718722# if _LIBCPP_STD_VER <= 17
719723 _LIBCPP_HIDE_FROM_ABI bool operator!=(const bitset& __rhs) const _NOEXCEPT;
720724# endif
721 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool test(size_t __pos) const;
722 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return __base::all(); }
723 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT { return __base::any(); }
724 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool none() const _NOEXCEPT { return !any(); }
725 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator<<(size_t __pos) const _NOEXCEPT;
726 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator>>(size_t __pos) const _NOEXCEPT;
725 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool test(size_t __pos) const;
726 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT {
727 return __base::all();
728 }
729 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT {
730 return __base::any();
731 }
732 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool none() const _NOEXCEPT { return !any(); }
733 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator<<(size_t __pos) const _NOEXCEPT;
734 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator>>(size_t __pos) const _NOEXCEPT;
727735
728736private:
729737 template <class _CharT, class _Traits>
......@@ -869,7 +877,16 @@ bitset<_Size>::to_string(char __zero, char __one) const {
869877
870878template <size_t _Size>
871879inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 size_t bitset<_Size>::count() const _NOEXCEPT {
872 return static_cast<size_t>(std::count(__base::__make_iter(0), __base::__make_iter(_Size), true));
880# if defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_CXX03_LANG)
881 if constexpr (_Size == 0) {
882 return 0;
883 } else if constexpr (_Size <= __base::__bits_per_word) {
884 return __builtin_popcountg(static_cast<unsigned _BitInt(_Size)>(__base::__first_));
885 } else
886# endif
887 {
888 return static_cast<size_t>(std::count(__base::__make_iter(0), __base::__make_iter(_Size), true));
889 }
873890}
874891
875892template <size_t _Size>
......@@ -912,7 +929,7 @@ bitset<_Size>::operator>>(size_t __pos) const _NOEXCEPT {
912929}
913930
914931template <size_t _Size>
915inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
932[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
916933operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
917934 bitset<_Size> __r = __x;
918935 __r &= __y;
......@@ -920,7 +937,7 @@ operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
920937}
921938
922939template <size_t _Size>
923inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
940[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
924941operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
925942 bitset<_Size> __r = __x;
926943 __r |= __y;
......@@ -928,7 +945,7 @@ operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
928945}
929946
930947template <size_t _Size>
931inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
948[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
932949operator^(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
933950 bitset<_Size> __r = __x;
934951 __r ^= __y;
......@@ -937,7 +954,9 @@ operator^(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
937954
938955template <size_t _Size>
939956struct hash<bitset<_Size> > : public __unary_function<bitset<_Size>, size_t> {
940 _LIBCPP_HIDE_FROM_ABI size_t operator()(const bitset<_Size>& __bs) const _NOEXCEPT { return __bs.__hash_code(); }
957 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const bitset<_Size>& __bs) const _NOEXCEPT {
958 return __bs.__hash_code();
959 }
941960};
942961
943962template <class _CharT, class _Traits, size_t _Size>
lib/libcxx/include/ccomplex+3-11
......@@ -26,18 +26,10 @@
2626# pragma GCC system_header
2727# endif
2828
29# if _LIBCPP_STD_VER >= 20
30
31using __standard_header_ccomplex
32 _LIBCPP_DEPRECATED_("removed in C++20. Include <complex> instead.") _LIBCPP_NODEBUG = void;
33using __use_standard_header_ccomplex _LIBCPP_NODEBUG = __standard_header_ccomplex;
34
35# elif _LIBCPP_STD_VER >= 17
36
37using __standard_header_ccomplex _LIBCPP_DEPRECATED_("Include <complex> instead.") _LIBCPP_NODEBUG = void;
38using __use_standard_header_ccomplex _LIBCPP_NODEBUG = __standard_header_ccomplex;
39
29# if _LIBCPP_STD_VER >= 17 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS
30# warning <ccomplex> is deprecated in C++17 and removed in C++20. Include <complex> instead.
4031# endif
32
4133#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
4234
4335#endif // _LIBCPP_CCOMPLEX
lib/libcxx/include/chrono+47
......@@ -218,6 +218,9 @@ template <class ToDuration, class Rep, class Period>
218218template <class ToDuration, class Rep, class Period>
219219 constexpr ToDuration round(const duration<Rep, Period>& d); // C++17
220220
221template <class T> struct is_clock; // C++20
222template <class T> inline constexpr bool is_clock_v = is_clock<T>::value; // C++20
223
221224// duration I/O
222225template<class charT, class traits, class Rep, class Period> // C++20
223226 basic_ostream<charT, traits>&
......@@ -1035,6 +1038,49 @@ constexpr chrono::year operator ""y(unsigned lo
10351038} // chrono_literals
10361039} // literals
10371040
1041namespace std {
1042 template<class T>
1043 struct hash; // C++26
1044 template<class Rep, class Period>
1045 struct hash<chrono::duration<Rep, Period>>; // C++26
1046 template<class Clock, class Duration>
1047 struct hash<chrono::time_point<Clock, Duration>>; // C++26
1048 template<>
1049 struct hash<chrono::day>; // C++26
1050 template<>
1051 struct hash<chrono::month>; // C++26
1052 template<>
1053 struct hash<chrono::year>; // C++26
1054 template<>
1055 struct hash<chrono::weekday>; // C++26
1056 template<>
1057 struct hash<chrono::weekday_indexed>; // C++26
1058 template<>
1059 struct hash<chrono::weekday_last>; // C++26
1060 template<>
1061 struct hash<chrono::month_day>; // C++26
1062 template<>
1063 struct hash<chrono::month_day_last>; // C++26
1064 template<>
1065 struct hash<chrono::month_weekday>; // C++26
1066 template<>
1067 struct hash<chrono::month_weekday_last>; // C++26
1068 template<>
1069 struct hash<chrono::year_month>; // C++26
1070 template<>
1071 struct hash<chrono::year_month_day>; // C++26
1072 template<>
1073 struct hash<chrono::year_month_day_last>; // C++26
1074 template<>
1075 struct hash<chrono::year_month_weekday>; // C++26
1076 template<>
1077 struct hash<chrono::year_month_weekday_last>; // C++26
1078 template<class Duration, class TimeZonePtr>
1079 struct hash<chrono::zoned_time<Duration, TimeZonePtr>>; // C++26
1080 template<>
1081 struct hash<chrono::leap_second>; // C++26
1082} // namespace std
1083
10381084} // std
10391085*/
10401086
......@@ -1057,6 +1103,7 @@ constexpr chrono::year operator ""y(unsigned lo
10571103# include <__chrono/day.h>
10581104# include <__chrono/exception.h>
10591105# include <__chrono/hh_mm_ss.h>
1106# include <__chrono/is_clock.h>
10601107# include <__chrono/literals.h>
10611108# include <__chrono/local_info.h>
10621109# include <__chrono/month.h>
lib/libcxx/include/ciso646+3-6
......@@ -24,13 +24,10 @@
2424# pragma GCC system_header
2525# endif
2626
27# if _LIBCPP_STD_VER >= 20
28
29using __standard_header_ciso646
30 _LIBCPP_DEPRECATED_("removed in C++20. Include <version> instead.") _LIBCPP_NODEBUG = void;
31using __use_standard_header_ciso646 _LIBCPP_NODEBUG = __standard_header_ciso646;
32
27# if _LIBCPP_STD_VER >= 20 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS
28# warning <ciso646> is removed in C++20. Include <version> instead.
3329# endif
30
3431#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
3532
3633#endif // _LIBCPP_CISO646
lib/libcxx/include/complex+77-65
......@@ -319,8 +319,8 @@ public:
319319 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 complex(const complex<_Xp>& __c)
320320 : __re_(__c.real()), __im_(__c.imag()) {}
321321
322 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type real() const { return __re_; }
323 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type imag() const { return __im_; }
322 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type real() const { return __re_; }
323 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type imag() const { return __im_; }
324324
325325 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; }
326326 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; }
......@@ -432,8 +432,8 @@ public:
432432 _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
433433 _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
434434
435 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float real() const { return __re_; }
436 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float imag() const { return __im_; }
435 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float real() const { return __re_; }
436 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float imag() const { return __im_; }
437437
438438 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; }
439439 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; }
......@@ -529,8 +529,8 @@ public:
529529 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
530530 _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
531531
532 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double real() const { return __re_; }
533 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double imag() const { return __im_; }
532 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double real() const { return __re_; }
533 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double imag() const { return __im_; }
534534
535535 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; }
536536 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; }
......@@ -630,8 +630,8 @@ public:
630630 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
631631 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
632632
633 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double real() const { return __re_; }
634 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double imag() const { return __im_; }
633 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double real() const { return __re_; }
634 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double imag() const { return __im_; }
635635
636636 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; }
637637 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; }
......@@ -732,7 +732,7 @@ inline _LIBCPP_CONSTEXPR complex<long double>::complex(const complex<double>& __
732732// 26.3.6 operators:
733733
734734template <class _Tp>
735inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
735[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
736736operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) {
737737 complex<_Tp> __t(__x);
738738 __t += __y;
......@@ -740,7 +740,7 @@ operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) {
740740}
741741
742742template <class _Tp>
743inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
743[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
744744operator+(const complex<_Tp>& __x, const _Tp& __y) {
745745 complex<_Tp> __t(__x);
746746 __t += __y;
......@@ -748,7 +748,7 @@ operator+(const complex<_Tp>& __x, const _Tp& __y) {
748748}
749749
750750template <class _Tp>
751inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
751[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
752752operator+(const _Tp& __x, const complex<_Tp>& __y) {
753753 complex<_Tp> __t(__y);
754754 __t += __x;
......@@ -756,7 +756,7 @@ operator+(const _Tp& __x, const complex<_Tp>& __y) {
756756}
757757
758758template <class _Tp>
759inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
759[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
760760operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) {
761761 complex<_Tp> __t(__x);
762762 __t -= __y;
......@@ -764,7 +764,7 @@ operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) {
764764}
765765
766766template <class _Tp>
767inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
767[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
768768operator-(const complex<_Tp>& __x, const _Tp& __y) {
769769 complex<_Tp> __t(__x);
770770 __t -= __y;
......@@ -772,7 +772,7 @@ operator-(const complex<_Tp>& __x, const _Tp& __y) {
772772}
773773
774774template <class _Tp>
775inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
775[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
776776operator-(const _Tp& __x, const complex<_Tp>& __y) {
777777 complex<_Tp> __t(-__y);
778778 __t += __x;
......@@ -780,13 +780,13 @@ operator-(const _Tp& __x, const complex<_Tp>& __y) {
780780}
781781
782782template <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> >
783_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
783[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
784784operator*(const complex<_Tp>& __lhs, const complex<_Tp>& __rhs) {
785785 return complex<_Tp>(__from_builtin_tag(), __lhs.__builtin() * __rhs.__builtin());
786786}
787787
788788template <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> >
789_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
789[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
790790operator*(const complex<_Tp>& __z, const complex<_Tp>& __w) {
791791 _Tp __a = __z.real();
792792 _Tp __b = __z.imag();
......@@ -797,7 +797,7 @@ operator*(const complex<_Tp>& __z, const complex<_Tp>& __w) {
797797}
798798
799799template <class _Tp>
800inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
800[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
801801operator*(const complex<_Tp>& __x, const _Tp& __y) {
802802 complex<_Tp> __t(__x);
803803 __t *= __y;
......@@ -805,7 +805,7 @@ operator*(const complex<_Tp>& __x, const _Tp& __y) {
805805}
806806
807807template <class _Tp>
808inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
808[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
809809operator*(const _Tp& __x, const complex<_Tp>& __y) {
810810 complex<_Tp> __t(__y);
811811 __t *= __x;
......@@ -813,13 +813,13 @@ operator*(const _Tp& __x, const complex<_Tp>& __y) {
813813}
814814
815815template <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> >
816_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
816[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
817817operator/(const complex<_Tp>& __lhs, const complex<_Tp>& __rhs) {
818818 return complex<_Tp>(__from_builtin_tag(), __lhs.__builtin() / __rhs.__builtin());
819819}
820820
821821template <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> >
822_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
822[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
823823operator/(const complex<_Tp>& __z, const complex<_Tp>& __w) {
824824 _Tp __a = __z.real();
825825 _Tp __b = __z.imag();
......@@ -831,13 +831,13 @@ operator/(const complex<_Tp>& __z, const complex<_Tp>& __w) {
831831}
832832
833833template <class _Tp>
834inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
834[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
835835operator/(const complex<_Tp>& __x, const _Tp& __y) {
836836 return complex<_Tp>(__x.real() / __y, __x.imag() / __y);
837837}
838838
839839template <class _Tp>
840inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
840[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
841841operator/(const _Tp& __x, const complex<_Tp>& __y) {
842842 complex<_Tp> __t(__x);
843843 __t /= __y;
......@@ -845,12 +845,14 @@ operator/(const _Tp& __x, const complex<_Tp>& __y) {
845845}
846846
847847template <class _Tp>
848inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator+(const complex<_Tp>& __x) {
848[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
849operator+(const complex<_Tp>& __x) {
849850 return __x;
850851}
851852
852853template <class _Tp>
853inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator-(const complex<_Tp>& __x) {
854[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
855operator-(const complex<_Tp>& __x) {
854856 return complex<_Tp>(-__x.real(), -__x.imag());
855857}
856858
......@@ -912,12 +914,13 @@ struct __libcpp_complex_overload_traits<_Tp, false, true> {
912914// real
913915
914916template <class _Tp>
915inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp real(const complex<_Tp>& __c) {
917[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp real(const complex<_Tp>& __c) {
916918 return __c.real();
917919}
918920
919921template <class _Tp>
920inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __libcpp_complex_overload_traits<_Tp>::_ValueType
922[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
923typename __libcpp_complex_overload_traits<_Tp>::_ValueType
921924real(_Tp __re) {
922925 return __re;
923926}
......@@ -925,12 +928,13 @@ real(_Tp __re) {
925928// imag
926929
927930template <class _Tp>
928inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp imag(const complex<_Tp>& __c) {
931[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp imag(const complex<_Tp>& __c) {
929932 return __c.imag();
930933}
931934
932935template <class _Tp>
933inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __libcpp_complex_overload_traits<_Tp>::_ValueType
936[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
937typename __libcpp_complex_overload_traits<_Tp>::_ValueType
934938imag(_Tp) {
935939 return 0;
936940}
......@@ -938,36 +942,36 @@ imag(_Tp) {
938942// abs
939943
940944template <class _Tp>
941inline _LIBCPP_HIDE_FROM_ABI _Tp abs(const complex<_Tp>& __c) {
945[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Tp abs(const complex<_Tp>& __c) {
942946 return std::hypot(__c.real(), __c.imag());
943947}
944948
945949// arg
946950
947951template <class _Tp>
948inline _LIBCPP_HIDE_FROM_ABI _Tp arg(const complex<_Tp>& __c) {
952[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Tp arg(const complex<_Tp>& __c) {
949953 return std::atan2(__c.imag(), __c.real());
950954}
951955
952956template <class _Tp, __enable_if_t<is_same<_Tp, long double>::value, int> = 0>
953inline _LIBCPP_HIDE_FROM_ABI long double arg(_Tp __re) {
957[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI long double arg(_Tp __re) {
954958 return std::atan2l(0.L, __re);
955959}
956960
957961template <class _Tp, __enable_if_t<is_integral<_Tp>::value || is_same<_Tp, double>::value, int> = 0>
958inline _LIBCPP_HIDE_FROM_ABI double arg(_Tp __re) {
962[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI double arg(_Tp __re) {
959963 return std::atan2(0., __re);
960964}
961965
962966template <class _Tp, __enable_if_t<is_same<_Tp, float>::value, int> = 0>
963inline _LIBCPP_HIDE_FROM_ABI float arg(_Tp __re) {
967[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI float arg(_Tp __re) {
964968 return std::atan2f(0.F, __re);
965969}
966970
967971// norm
968972
969973template <class _Tp>
970inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp norm(const complex<_Tp>& __c) {
974[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp norm(const complex<_Tp>& __c) {
971975 if (std::__constexpr_isinf(__c.real()))
972976 return std::abs(__c.real());
973977 if (std::__constexpr_isinf(__c.imag()))
......@@ -976,7 +980,8 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp norm(const comple
976980}
977981
978982template <class _Tp>
979inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __libcpp_complex_overload_traits<_Tp>::_ValueType
983[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
984typename __libcpp_complex_overload_traits<_Tp>::_ValueType
980985norm(_Tp __re) {
981986 typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType;
982987 return static_cast<_ValueType>(__re) * __re;
......@@ -985,12 +990,14 @@ norm(_Tp __re) {
985990// conj
986991
987992template <class _Tp>
988inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> conj(const complex<_Tp>& __c) {
993[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
994conj(const complex<_Tp>& __c) {
989995 return complex<_Tp>(__c.real(), -__c.imag());
990996}
991997
992998template <class _Tp>
993inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
999[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1000typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
9941001conj(_Tp __re) {
9951002 typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
9961003 return _ComplexType(__re);
......@@ -999,7 +1006,7 @@ conj(_Tp __re) {
9991006// proj
10001007
10011008template <class _Tp>
1002inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> proj(const complex<_Tp>& __c) {
1009[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> proj(const complex<_Tp>& __c) {
10031010 complex<_Tp> __r = __c;
10041011 if (std::isinf(__c.real()) || std::isinf(__c.imag()))
10051012 __r = complex<_Tp>(INFINITY, std::copysign(_Tp(0), __c.imag()));
......@@ -1007,14 +1014,16 @@ inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> proj(const complex<_Tp>& __c) {
10071014}
10081015
10091016template <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0>
1010inline _LIBCPP_HIDE_FROM_ABI typename __libcpp_complex_overload_traits<_Tp>::_ComplexType proj(_Tp __re) {
1017[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
1018proj(_Tp __re) {
10111019 if (std::isinf(__re))
10121020 __re = std::abs(__re);
10131021 return complex<_Tp>(__re);
10141022}
10151023
10161024template <class _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0>
1017inline _LIBCPP_HIDE_FROM_ABI typename __libcpp_complex_overload_traits<_Tp>::_ComplexType proj(_Tp __re) {
1025[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
1026proj(_Tp __re) {
10181027 typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
10191028 return _ComplexType(__re);
10201029}
......@@ -1022,7 +1031,7 @@ inline _LIBCPP_HIDE_FROM_ABI typename __libcpp_complex_overload_traits<_Tp>::_Co
10221031// polar
10231032
10241033template <class _Tp>
1025_LIBCPP_HIDE_FROM_ABI complex<_Tp> polar(const _Tp& __rho, const _Tp& __theta = _Tp()) {
1034[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> polar(const _Tp& __rho, const _Tp& __theta = _Tp()) {
10261035 if (std::isnan(__rho) || std::signbit(__rho))
10271036 return complex<_Tp>(_Tp(NAN), _Tp(NAN));
10281037 if (std::isnan(__theta)) {
......@@ -1047,21 +1056,21 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> polar(const _Tp& __rho, const _Tp& __theta =
10471056// log
10481057
10491058template <class _Tp>
1050inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> log(const complex<_Tp>& __x) {
1059[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> log(const complex<_Tp>& __x) {
10511060 return complex<_Tp>(std::log(std::abs(__x)), std::arg(__x));
10521061}
10531062
10541063// log10
10551064
10561065template <class _Tp>
1057inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> log10(const complex<_Tp>& __x) {
1066[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> log10(const complex<_Tp>& __x) {
10581067 return std::log(__x) / std::log(_Tp(10));
10591068}
10601069
10611070// sqrt
10621071
10631072template <class _Tp>
1064_LIBCPP_HIDE_FROM_ABI complex<_Tp> sqrt(const complex<_Tp>& __x) {
1073[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> sqrt(const complex<_Tp>& __x) {
10651074 if (std::isinf(__x.imag()))
10661075 return complex<_Tp>(_Tp(INFINITY), __x.imag());
10671076 if (std::isinf(__x.real())) {
......@@ -1075,7 +1084,7 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> sqrt(const complex<_Tp>& __x) {
10751084// exp
10761085
10771086template <class _Tp>
1078_LIBCPP_HIDE_FROM_ABI complex<_Tp> exp(const complex<_Tp>& __x) {
1087[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> exp(const complex<_Tp>& __x) {
10791088 _Tp __i = __x.imag();
10801089 if (__i == 0) {
10811090 return complex<_Tp>(std::exp(__x.real()), std::copysign(_Tp(0), __x.imag()));
......@@ -1097,24 +1106,27 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> exp(const complex<_Tp>& __x) {
10971106// pow
10981107
10991108template <class _Tp>
1100inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> pow(const complex<_Tp>& __x, const complex<_Tp>& __y) {
1109[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> pow(const complex<_Tp>& __x, const complex<_Tp>& __y) {
11011110 return std::exp(__y * std::log(__x));
11021111}
11031112
11041113template <class _Tp, class _Up, __enable_if_t<is_floating_point<_Tp>::value && is_floating_point<_Up>::value, int> = 0>
1105inline _LIBCPP_HIDE_FROM_ABI complex<__promote_t<_Tp, _Up> > pow(const complex<_Tp>& __x, const complex<_Up>& __y) {
1114[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI complex<__promote_t<_Tp, _Up> >
1115pow(const complex<_Tp>& __x, const complex<_Up>& __y) {
11061116 typedef complex<__promote_t<_Tp, _Up> > result_type;
11071117 return std::pow(result_type(__x), result_type(__y));
11081118}
11091119
11101120template <class _Tp, class _Up, __enable_if_t<is_floating_point<_Tp>::value && is_arithmetic<_Up>::value, int> = 0>
1111inline _LIBCPP_HIDE_FROM_ABI complex<__promote_t<_Tp, _Up> > pow(const complex<_Tp>& __x, const _Up& __y) {
1121[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI complex<__promote_t<_Tp, _Up> >
1122pow(const complex<_Tp>& __x, const _Up& __y) {
11121123 typedef complex<__promote_t<_Tp, _Up> > result_type;
11131124 return std::pow(result_type(__x), result_type(__y));
11141125}
11151126
11161127template <class _Tp, class _Up, __enable_if_t<is_arithmetic<_Tp>::value && is_floating_point<_Up>::value, int> = 0>
1117inline _LIBCPP_HIDE_FROM_ABI complex<__promote_t<_Tp, _Up> > pow(const _Tp& __x, const complex<_Up>& __y) {
1128[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI complex<__promote_t<_Tp, _Up> >
1129pow(const _Tp& __x, const complex<_Up>& __y) {
11181130 typedef complex<__promote_t<_Tp, _Up> > result_type;
11191131 return std::pow(result_type(__x), result_type(__y));
11201132}
......@@ -1129,7 +1141,7 @@ inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> __sqr(const complex<_Tp>& __x) {
11291141// asinh
11301142
11311143template <class _Tp>
1132_LIBCPP_HIDE_FROM_ABI complex<_Tp> asinh(const complex<_Tp>& __x) {
1144[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> asinh(const complex<_Tp>& __x) {
11331145 const _Tp __pi(atan2(+0., -0.));
11341146 if (std::isinf(__x.real())) {
11351147 if (std::isnan(__x.imag()))
......@@ -1154,7 +1166,7 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> asinh(const complex<_Tp>& __x) {
11541166// acosh
11551167
11561168template <class _Tp>
1157_LIBCPP_HIDE_FROM_ABI complex<_Tp> acosh(const complex<_Tp>& __x) {
1169[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> acosh(const complex<_Tp>& __x) {
11581170 const _Tp __pi(atan2(+0., -0.));
11591171 if (std::isinf(__x.real())) {
11601172 if (std::isnan(__x.imag()))
......@@ -1183,7 +1195,7 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> acosh(const complex<_Tp>& __x) {
11831195// atanh
11841196
11851197template <class _Tp>
1186_LIBCPP_HIDE_FROM_ABI complex<_Tp> atanh(const complex<_Tp>& __x) {
1198[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> atanh(const complex<_Tp>& __x) {
11871199 const _Tp __pi(atan2(+0., -0.));
11881200 if (std::isinf(__x.imag())) {
11891201 return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi / _Tp(2), __x.imag()));
......@@ -1209,7 +1221,7 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> atanh(const complex<_Tp>& __x) {
12091221// sinh
12101222
12111223template <class _Tp>
1212_LIBCPP_HIDE_FROM_ABI complex<_Tp> sinh(const complex<_Tp>& __x) {
1224[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> sinh(const complex<_Tp>& __x) {
12131225 if (std::isinf(__x.real()) && !std::isfinite(__x.imag()))
12141226 return complex<_Tp>(__x.real(), _Tp(NAN));
12151227 if (__x.real() == 0 && !std::isfinite(__x.imag()))
......@@ -1222,7 +1234,7 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> sinh(const complex<_Tp>& __x) {
12221234// cosh
12231235
12241236template <class _Tp>
1225_LIBCPP_HIDE_FROM_ABI complex<_Tp> cosh(const complex<_Tp>& __x) {
1237[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> cosh(const complex<_Tp>& __x) {
12261238 if (std::isinf(__x.real()) && !std::isfinite(__x.imag()))
12271239 return complex<_Tp>(std::abs(__x.real()), _Tp(NAN));
12281240 if (__x.real() == 0 && !std::isfinite(__x.imag()))
......@@ -1237,7 +1249,7 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> cosh(const complex<_Tp>& __x) {
12371249// tanh
12381250
12391251template <class _Tp>
1240_LIBCPP_HIDE_FROM_ABI complex<_Tp> tanh(const complex<_Tp>& __x) {
1252[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> tanh(const complex<_Tp>& __x) {
12411253 if (std::isinf(__x.real())) {
12421254 if (!std::isfinite(__x.imag()))
12431255 return complex<_Tp>(std::copysign(_Tp(1), __x.real()), _Tp(0));
......@@ -1257,7 +1269,7 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> tanh(const complex<_Tp>& __x) {
12571269// asin
12581270
12591271template <class _Tp>
1260_LIBCPP_HIDE_FROM_ABI complex<_Tp> asin(const complex<_Tp>& __x) {
1272[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> asin(const complex<_Tp>& __x) {
12611273 complex<_Tp> __z = std::asinh(complex<_Tp>(-__x.imag(), __x.real()));
12621274 return complex<_Tp>(__z.imag(), -__z.real());
12631275}
......@@ -1265,7 +1277,7 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> asin(const complex<_Tp>& __x) {
12651277// acos
12661278
12671279template <class _Tp>
1268_LIBCPP_HIDE_FROM_ABI complex<_Tp> acos(const complex<_Tp>& __x) {
1280[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> acos(const complex<_Tp>& __x) {
12691281 const _Tp __pi(atan2(+0., -0.));
12701282 if (std::isinf(__x.real())) {
12711283 if (std::isnan(__x.imag()))
......@@ -1297,7 +1309,7 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> acos(const complex<_Tp>& __x) {
12971309// atan
12981310
12991311template <class _Tp>
1300_LIBCPP_HIDE_FROM_ABI complex<_Tp> atan(const complex<_Tp>& __x) {
1312[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> atan(const complex<_Tp>& __x) {
13011313 complex<_Tp> __z = std::atanh(complex<_Tp>(-__x.imag(), __x.real()));
13021314 return complex<_Tp>(__z.imag(), -__z.real());
13031315}
......@@ -1305,7 +1317,7 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> atan(const complex<_Tp>& __x) {
13051317// sin
13061318
13071319template <class _Tp>
1308_LIBCPP_HIDE_FROM_ABI complex<_Tp> sin(const complex<_Tp>& __x) {
1320[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> sin(const complex<_Tp>& __x) {
13091321 complex<_Tp> __z = std::sinh(complex<_Tp>(-__x.imag(), __x.real()));
13101322 return complex<_Tp>(__z.imag(), -__z.real());
13111323}
......@@ -1313,14 +1325,14 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> sin(const complex<_Tp>& __x) {
13131325// cos
13141326
13151327template <class _Tp>
1316inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> cos(const complex<_Tp>& __x) {
1328[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> cos(const complex<_Tp>& __x) {
13171329 return std::cosh(complex<_Tp>(-__x.imag(), __x.real()));
13181330}
13191331
13201332// tan
13211333
13221334template <class _Tp>
1323_LIBCPP_HIDE_FROM_ABI complex<_Tp> tan(const complex<_Tp>& __x) {
1335[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI complex<_Tp> tan(const complex<_Tp>& __x) {
13241336 complex<_Tp> __z = std::tanh(complex<_Tp>(-__x.imag(), __x.real()));
13251337 return complex<_Tp>(__z.imag(), -__z.real());
13261338}
......@@ -1398,7 +1410,7 @@ struct tuple_element<_Ip, complex<_Tp>> {
13981410};
13991411
14001412template <size_t _Ip, class _Xp>
1401_LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>& __z) noexcept {
1413[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>& __z) noexcept {
14021414 static_assert(_Ip < 2, "Index value is out of range.");
14031415 if constexpr (_Ip == 0) {
14041416 return __z.__re_;
......@@ -1408,7 +1420,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>& __z) noexcept {
14081420}
14091421
14101422template <size_t _Ip, class _Xp>
1411_LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&& __z) noexcept {
1423[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&& __z) noexcept {
14121424 static_assert(_Ip < 2, "Index value is out of range.");
14131425 if constexpr (_Ip == 0) {
14141426 return std::move(__z.__re_);
......@@ -1418,7 +1430,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&& __z) noexcept {
14181430}
14191431
14201432template <size_t _Ip, class _Xp>
1421_LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>& __z) noexcept {
1433[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>& __z) noexcept {
14221434 static_assert(_Ip < 2, "Index value is out of range.");
14231435 if constexpr (_Ip == 0) {
14241436 return __z.__re_;
......@@ -1428,7 +1440,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>& __z) noexcept
14281440}
14291441
14301442template <size_t _Ip, class _Xp>
1431_LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&& __z) noexcept {
1443[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&& __z) noexcept {
14321444 static_assert(_Ip < 2, "Index value is out of range.");
14331445 if constexpr (_Ip == 0) {
14341446 return std::move(__z.__re_);
lib/libcxx/include/complex.h+10-10
......@@ -18,19 +18,19 @@
1818*/
1919
2020#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
21# include <__cxx03/complex.h>
21# include <__cxx03/__config>
2222#else
2323# include <__config>
24#endif
2425
25# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26# pragma GCC system_header
27# endif
26#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27# pragma GCC system_header
28#endif
2829
29# ifdef __cplusplus
30# include <complex>
31# elif __has_include_next(<complex.h>)
32# include_next <complex.h>
33# endif
34#endif // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
30#ifdef __cplusplus
31# include <complex>
32#elif __has_include_next(<complex.h>)
33# include_next <complex.h>
34#endif
3535
3636#endif // _LIBCPP_COMPLEX_H
lib/libcxx/include/condition_variable+3-3
......@@ -206,14 +206,14 @@ public:
206206# if _LIBCPP_STD_VER >= 20
207207
208208 template <class _Lock, class _Predicate>
209 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool wait(_Lock& __lock, stop_token __stoken, _Predicate __pred);
209 _LIBCPP_HIDE_FROM_ABI bool wait(_Lock& __lock, stop_token __stoken, _Predicate __pred);
210210
211211 template <class _Lock, class _Clock, class _Duration, class _Predicate>
212 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool wait_until(
212 _LIBCPP_HIDE_FROM_ABI bool wait_until(
213213 _Lock& __lock, stop_token __stoken, const chrono::time_point<_Clock, _Duration>& __abs_time, _Predicate __pred);
214214
215215 template <class _Lock, class _Rep, class _Period, class _Predicate>
216 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool
216 _LIBCPP_HIDE_FROM_ABI bool
217217 wait_for(_Lock& __lock, stop_token __stoken, const chrono::duration<_Rep, _Period>& __rel_time, _Predicate __pred);
218218
219219# endif // _LIBCPP_STD_VER >= 20
lib/libcxx/include/cstdalign+3-10
......@@ -43,17 +43,10 @@ Macros:
4343# undef __alignof_is_defined
4444# define __alignof_is_defined 1
4545
46# if _LIBCPP_STD_VER >= 20
47
48using __standard_header_cstdalign _LIBCPP_DEPRECATED_("removed in C++20.") _LIBCPP_NODEBUG = void;
49using __use_standard_header_cstdalign _LIBCPP_NODEBUG = __standard_header_cstdalign;
50
51# elif _LIBCPP_STD_VER >= 17
52
53using __standard_header_cstdalign _LIBCPP_DEPRECATED _LIBCPP_NODEBUG = void;
54using __use_standard_header_cstdalign _LIBCPP_NODEBUG = __standard_header_cstdalign;
55
46# if _LIBCPP_STD_VER >= 17 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS
47# warning <cstdalign> is deprecated in C++17 and removed in C++20.
5648# endif
49
5750#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
5851
5952#endif // _LIBCPP_CSTDALIGN
lib/libcxx/include/cstdbool+3-10
......@@ -31,17 +31,10 @@ Macros:
3131# undef __bool_true_false_are_defined
3232# define __bool_true_false_are_defined 1
3333
34# if _LIBCPP_STD_VER >= 20
35
36using __standard_header_cstdbool _LIBCPP_DEPRECATED_("removed in C++20.") _LIBCPP_NODEBUG = void;
37using __use_standard_header_cstdbool _LIBCPP_NODEBUG = __standard_header_cstdbool;
38
39# elif _LIBCPP_STD_VER >= 17
40
41using __standard_header_cstdbool _LIBCPP_DEPRECATED _LIBCPP_NODEBUG = void;
42using __use_standard_header_cstdbool _LIBCPP_NODEBUG = __standard_header_cstdbool;
43
34# if _LIBCPP_STD_VER >= 17 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS
35# warning <cstdbool> is deprecated in C++17 and removed in C++20.
4436# endif
37
4538#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
4639
4740#endif // _LIBCPP_CSTDBOOL
lib/libcxx/include/ctgmath+2-11
......@@ -28,17 +28,8 @@
2828# pragma GCC system_header
2929# endif
3030
31# if _LIBCPP_STD_VER >= 20
32
33using __standard_header_ctgmath
34 _LIBCPP_DEPRECATED_("removed in C++20. Include <cmath> and <complex> instead.") _LIBCPP_NODEBUG = void;
35using __use_standard_header_ctgmath _LIBCPP_NODEBUG = __standard_header_ctgmath;
36
37# elif _LIBCPP_STD_VER >= 17
38
39using __standard_header_ctgmath _LIBCPP_DEPRECATED_("Include <cmath> and <complex> instead.") _LIBCPP_NODEBUG = void;
40using __use_standard_header_ctgmath _LIBCPP_NODEBUG = __standard_header_ctgmath;
41
31# if _LIBCPP_STD_VER >= 17 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS
32# warning <ctgmath> is deprecated in C++17 and removed in C++20. Include <cmath> and <complex> instead.
4233# endif
4334
4435#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
lib/libcxx/include/ctype.h+24-24
......@@ -30,36 +30,36 @@ int toupper(int c);
3030*/
3131
3232#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
33# include <__cxx03/ctype.h>
33# include <__cxx03/__config>
3434#else
3535# include <__config>
36#endif
3637
37# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
38# pragma GCC system_header
39# endif
38#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
39# pragma GCC system_header
40#endif
4041
41# if __has_include_next(<ctype.h>)
42# include_next <ctype.h>
43# endif
42#if __has_include_next(<ctype.h>)
43# include_next <ctype.h>
44#endif
4445
45# ifdef __cplusplus
46#ifdef __cplusplus
4647
47# undef isalnum
48# undef isalpha
49# undef isblank
50# undef iscntrl
51# undef isdigit
52# undef isgraph
53# undef islower
54# undef isprint
55# undef ispunct
56# undef isspace
57# undef isupper
58# undef isxdigit
59# undef tolower
60# undef toupper
48# undef isalnum
49# undef isalpha
50# undef isblank
51# undef iscntrl
52# undef isdigit
53# undef isgraph
54# undef islower
55# undef isprint
56# undef ispunct
57# undef isspace
58# undef isupper
59# undef isxdigit
60# undef tolower
61# undef toupper
6162
62# endif
63#endif // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
63#endif
6464
6565#endif // _LIBCPP_CTYPE_H
lib/libcxx/include/cwchar+2-2
......@@ -231,8 +231,8 @@ __constexpr_wmemcmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __count)
231231
232232template <class _Tp, class _Up>
233233_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __constexpr_wmemchr(_Tp* __str, _Up __value, size_t __count) {
234 static_assert(sizeof(_Tp) == sizeof(wchar_t)&& _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t) &&
235 __libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value,
234 static_assert(sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t) &&
235 __is_trivially_equality_comparable_v<_Tp, _Tp>,
236236 "Calling wmemchr on non-trivially equality comparable types is unsafe.");
237237
238238# if __has_builtin(__builtin_wmemchr)
lib/libcxx/include/deque+109-225
......@@ -191,9 +191,9 @@ template <class T, class Allocator, class Predicate>
191191# include <__algorithm/min.h>
192192# include <__algorithm/move.h>
193193# include <__algorithm/move_backward.h>
194# include <__algorithm/ranges_copy_n.h>
194195# include <__algorithm/remove.h>
195196# include <__algorithm/remove_if.h>
196# include <__algorithm/unwrap_iter.h>
197197# include <__assert>
198198# include <__config>
199199# include <__debug_utils/sanitizers.h>
......@@ -220,21 +220,19 @@ template <class T, class Allocator, class Predicate>
220220# include <__ranges/concepts.h>
221221# include <__ranges/container_compatible_range.h>
222222# include <__ranges/from_range.h>
223# include <__ranges/size.h>
224223# include <__split_buffer>
225224# include <__type_traits/conditional.h>
226225# include <__type_traits/container_traits.h>
227# include <__type_traits/disjunction.h>
228226# include <__type_traits/enable_if.h>
229227# include <__type_traits/is_allocator.h>
230228# include <__type_traits/is_convertible.h>
231229# include <__type_traits/is_nothrow_assignable.h>
232230# include <__type_traits/is_nothrow_constructible.h>
233# include <__type_traits/is_replaceable.h>
234231# include <__type_traits/is_same.h>
235232# include <__type_traits/is_swappable.h>
236233# include <__type_traits/is_trivially_relocatable.h>
237234# include <__type_traits/type_identity.h>
235# include <__utility/exception_guard.h>
238236# include <__utility/forward.h>
239237# include <__utility/move.h>
240238# include <__utility/pair.h>
......@@ -461,9 +459,8 @@ private:
461459 __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>;
462460
463461public:
464 using __is_segmented_iterator _LIBCPP_NODEBUG = true_type;
465 using __segment_iterator _LIBCPP_NODEBUG = _MapPointer;
466 using __local_iterator _LIBCPP_NODEBUG = _Pointer;
462 using __segment_iterator _LIBCPP_NODEBUG = _MapPointer;
463 using __local_iterator _LIBCPP_NODEBUG = _Pointer;
467464
468465 static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; }
469466 static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; }
......@@ -488,6 +485,9 @@ const _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer,
488485
489486template <class _Tp, class _Allocator /*= allocator<_Tp>*/>
490487class deque {
488 template <class _Up, class _Alloc>
489 using __split_buffer _LIBCPP_NODEBUG = std::__split_buffer<_Up, _Alloc, __split_buffer_pointer_layout>;
490
491491public:
492492 // types:
493493
......@@ -531,10 +531,6 @@ public:
531531 __libcpp_is_trivially_relocatable<__map>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
532532 deque,
533533 void>;
534 using __replaceable _LIBCPP_NODEBUG =
535 __conditional_t<__is_replaceable_v<__map> && __container_allocator_is_replaceable<__alloc_traits>::value,
536 deque,
537 void>;
538534
539535 static_assert(is_nothrow_default_constructible<allocator_type>::value ==
540536 is_nothrow_default_constructible<__pointer_allocator>::value,
......@@ -635,7 +631,7 @@ public:
635631# endif
636632 _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v);
637633
638 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
634 template <__enable_if_t<__is_allocator_v<_Allocator>, int> = 0>
639635 _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a)
640636 : __map_(__pointer_allocator(__a)), __start_(0), __size_(0), __alloc_(__a) {
641637 __annotate_new(0);
......@@ -703,8 +699,16 @@ public:
703699 __assign_with_size_random_access(ranges::begin(__range), __n);
704700
705701 } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
706 auto __n = static_cast<size_type>(ranges::distance(__range));
707 __assign_with_size(ranges::begin(__range), __n);
702 auto __n = ranges::distance(__range);
703 auto __first = ranges::begin(__range);
704
705 auto __result = std::ranges::copy_n(std::move(__first), std::min<size_t>(__n, size()), begin());
706
707 if (static_cast<size_type>(__n) > size()) {
708 __append_with_size(std::move(__result.in), __n - size());
709 } else {
710 __erase_to_end(__result.out);
711 }
708712
709713 } else {
710714 __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
......@@ -720,45 +724,53 @@ public:
720724
721725 // iterators:
722726
723 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
727 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
724728 __map_pointer __mp = __map_.begin() + __start_ / __block_size;
725729 return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
726730 }
727731
728 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
732 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
729733 __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);
730734 return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
731735 }
732736
733 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
737 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
734738 size_type __p = size() + __start_;
735739 __map_pointer __mp = __map_.begin() + __p / __block_size;
736740 return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
737741 }
738742
739 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
743 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
740744 size_type __p = size() + __start_;
741745 __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);
742746 return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
743747 }
744748
745 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
746 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
747 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
748 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
749 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
750 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
751 return const_reverse_iterator(end());
752 }
753 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
754 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
755 return const_reverse_iterator(begin());
756 }
749757
750 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
751 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
752 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
753 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
758 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
759 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
760 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT {
761 return const_reverse_iterator(end());
762 }
763 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {
764 return const_reverse_iterator(begin());
765 }
754766
755767 // capacity:
756 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size(); }
768 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size(); }
757769
758770 _LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_; }
759771 _LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_; }
760772
761 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
773 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
762774 return std::min<size_type>(__alloc_traits::max_size(__alloc()), numeric_limits<difference_type>::max());
763775 }
764776 _LIBCPP_HIDE_FROM_ABI void resize(size_type __n);
......@@ -767,18 +779,22 @@ public:
767779 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; }
768780
769781 // element access:
770 _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __i) _NOEXCEPT;
771 _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __i) const _NOEXCEPT;
772 _LIBCPP_HIDE_FROM_ABI reference at(size_type __i);
773 _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __i) const;
774 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT;
775 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT;
776 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT;
777 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT;
782 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __i) _NOEXCEPT;
783 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __i) const _NOEXCEPT;
784 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference at(size_type __i);
785 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __i) const;
786 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT;
787 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT;
788 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT;
789 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT;
778790
779791 // 23.2.2.3 modifiers:
780792 _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v);
781793 _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v);
794
795 template <class... _Args>
796 _LIBCPP_HIDE_FROM_ABI iterator __emplace(const_iterator __p, _Args&&... __args);
797
782798# ifndef _LIBCPP_CXX03_LANG
783799# if _LIBCPP_STD_VER >= 17
784800 template <class... _Args>
......@@ -791,8 +807,11 @@ public:
791807 template <class... _Args>
792808 _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args);
793809# endif
810
794811 template <class... _Args>
795 _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args);
812 _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args) {
813 return __emplace(__p, std::forward<_Args>(__args)...);
814 }
796815
797816 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v);
798817 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v);
......@@ -805,17 +824,21 @@ public:
805824
806825 template <_ContainerCompatibleRange<_Tp> _Range>
807826 _LIBCPP_HIDE_FROM_ABI void append_range(_Range&& __range) {
808 insert_range(end(), std::forward<_Range>(__range));
827 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) {
828 __append_with_size(ranges::begin(__range), ranges::distance(__range));
829 } else {
830 __append_with_sentinel(ranges::begin(__range), ranges::end(__range));
831 }
809832 }
810833# endif
811834
812 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v);
835 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) { return __emplace(__p, std::move(__v)); }
813836
814837 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, initializer_list<value_type> __il) {
815838 return insert(__p, __il.begin(), __il.end());
816839 }
817840# endif // _LIBCPP_CXX03_LANG
818 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v);
841 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) { return __emplace(__p, __v); }
819842 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v);
820843 template <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> = 0>
821844 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l);
......@@ -1109,7 +1132,7 @@ public:
11091132 // This function tests deque object annotations.
11101133 if (empty()) {
11111134 for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) {
1112 if (!__sanitizer_verify_double_ended_contiguous_container(
1135 if (!::__sanitizer_verify_double_ended_contiguous_container(
11131136 std::__to_address(*__it),
11141137 std::__to_address(*__it),
11151138 std::__to_address(*__it),
......@@ -1141,7 +1164,7 @@ public:
11411164
11421165 // Is the block before or after deque blocks that contain elements?
11431166 if (__it < __first_mp || __it > __last_mp) {
1144 if (!__sanitizer_verify_double_ended_contiguous_container(
1167 if (!::__sanitizer_verify_double_ended_contiguous_container(
11451168 std::__to_address(*__it),
11461169 std::__to_address(*__it),
11471170 std::__to_address(*__it),
......@@ -1151,7 +1174,7 @@ public:
11511174 const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it);
11521175 const void* __containers_buffer_end =
11531176 (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size);
1154 if (!__sanitizer_verify_double_ended_contiguous_container(
1177 if (!::__sanitizer_verify_double_ended_contiguous_container(
11551178 std::__to_address(*__it),
11561179 __containers_buffer_beg,
11571180 __containers_buffer_end,
......@@ -1191,7 +1214,7 @@ private:
11911214
11921215 template <class _RandomAccessIterator>
11931216 _LIBCPP_HIDE_FROM_ABI void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n);
1194 template <class _Iterator>
1217 template <class _AlgPolicy, class _Iterator>
11951218 _LIBCPP_HIDE_FROM_ABI void __assign_with_size(_Iterator __f, difference_type __n);
11961219
11971220 template <class _Iterator, class _Sentinel>
......@@ -1239,8 +1262,8 @@ private:
12391262 clear();
12401263 shrink_to_fit();
12411264 }
1242 __alloc() = __c.__alloc();
1243 __map_.__alloc_ = __c.__map_.__alloc_;
1265 __alloc() = __c.__alloc();
1266 __map_.__get_allocator() = __c.__map_.__get_allocator();
12441267 }
12451268
12461269 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque&, false_type) {}
......@@ -1256,22 +1279,22 @@ _LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque
12561279
12571280# if _LIBCPP_STD_VER >= 17
12581281template <class _InputIterator,
1259 class _Alloc = allocator<__iter_value_type<_InputIterator>>,
1282 class _Alloc = allocator<__iterator_value_type<_InputIterator>>,
12601283 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1261 class = enable_if_t<__is_allocator<_Alloc>::value> >
1262deque(_InputIterator, _InputIterator) -> deque<__iter_value_type<_InputIterator>, _Alloc>;
1284 class = enable_if_t<__is_allocator_v<_Alloc>>>
1285deque(_InputIterator, _InputIterator) -> deque<__iterator_value_type<_InputIterator>, _Alloc>;
12631286
12641287template <class _InputIterator,
12651288 class _Alloc,
12661289 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1267 class = enable_if_t<__is_allocator<_Alloc>::value> >
1268deque(_InputIterator, _InputIterator, _Alloc) -> deque<__iter_value_type<_InputIterator>, _Alloc>;
1290 class = enable_if_t<__is_allocator_v<_Alloc>>>
1291deque(_InputIterator, _InputIterator, _Alloc) -> deque<__iterator_value_type<_InputIterator>, _Alloc>;
12691292# endif
12701293
12711294# if _LIBCPP_STD_VER >= 23
12721295template <ranges::input_range _Range,
12731296 class _Alloc = allocator<ranges::range_value_t<_Range>>,
1274 class = enable_if_t<__is_allocator<_Alloc>::value> >
1297 class = enable_if_t<__is_allocator_v<_Alloc>>>
12751298deque(from_range_t, _Range&&, _Alloc = _Alloc()) -> deque<ranges::range_value_t<_Range>, _Alloc>;
12761299# endif
12771300
......@@ -1319,7 +1342,7 @@ deque<_Tp, _Allocator>::deque(const deque& __c)
13191342 : __map_(__pointer_allocator(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))),
13201343 __start_(0),
13211344 __size_(0),
1322 __alloc_(__map_.__alloc_) {
1345 __alloc_(__map_.__get_allocator()) {
13231346 __annotate_new(0);
13241347 __append(__c.begin(), __c.end());
13251348}
......@@ -1451,24 +1474,6 @@ deque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator _
14511474 __erase_to_end(std::copy_n(__f, __n, begin()));
14521475}
14531476
1454template <class _Tp, class _Allocator>
1455template <class _Iterator>
1456_LIBCPP_HIDE_FROM_ABI void deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) {
1457 if (static_cast<size_type>(__n) > size()) {
1458 auto __added_size = __n - size();
1459
1460 auto __i = begin();
1461 for (auto __count = size(); __count != 0; --__count) {
1462 *__i++ = *__f++;
1463 }
1464
1465 __append_with_size(__f, __added_size);
1466
1467 } else {
1468 __erase_to_end(std::copy_n(__f, __n, begin()));
1469 }
1470}
1471
14721477template <class _Tp, class _Allocator>
14731478void deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v) {
14741479 if (__n > size()) {
......@@ -1661,56 +1666,11 @@ deque<_Tp, _Allocator>::emplace_front(_Args&&... __args) {
16611666 return *begin();
16621667# endif
16631668}
1664
1665template <class _Tp, class _Allocator>
1666typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v) {
1667 size_type __pos = __p - begin();
1668 size_type __to_end = size() - __pos;
1669 allocator_type& __a = __alloc();
1670 if (__pos < __to_end) { // insert by shifting things backward
1671 if (__front_spare() == 0)
1672 __add_front_capacity();
1673 // __front_spare() >= 1
1674 __annotate_increase_front(1);
1675 if (__pos == 0) {
1676 __alloc_traits::construct(__a, std::addressof(*--begin()), std::move(__v));
1677 --__start_;
1678 ++__size();
1679 } else {
1680 iterator __b = begin();
1681 iterator __bm1 = std::prev(__b);
1682 __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b));
1683 --__start_;
1684 ++__size();
1685 if (__pos > 1)
1686 __b = std::move(std::next(__b), __b + __pos, __b);
1687 *__b = std::move(__v);
1688 }
1689 } else { // insert by shifting things forward
1690 if (__back_spare() == 0)
1691 __add_back_capacity();
1692 // __back_capacity >= 1
1693 __annotate_increase_back(1);
1694 size_type __de = size() - __pos;
1695 if (__de == 0) {
1696 __alloc_traits::construct(__a, std::addressof(*end()), std::move(__v));
1697 ++__size();
1698 } else {
1699 iterator __e = end();
1700 iterator __em1 = std::prev(__e);
1701 __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1));
1702 ++__size();
1703 if (__de > 1)
1704 __e = std::move_backward(__e - __de, __em1, __e);
1705 *--__e = std::move(__v);
1706 }
1707 }
1708 return begin() + __pos;
1709}
1669# endif // _LIBCPP_CXX03_LANG
17101670
17111671template <class _Tp, class _Allocator>
17121672template <class... _Args>
1713typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) {
1673typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::__emplace(const_iterator __p, _Args&&... __args) {
17141674 size_type __pos = __p - begin();
17151675 size_type __to_end = size() - __pos;
17161676 allocator_type& __a = __alloc();
......@@ -1757,60 +1717,6 @@ typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::emplace(const_
17571717 return begin() + __pos;
17581718}
17591719
1760# endif // _LIBCPP_CXX03_LANG
1761
1762template <class _Tp, class _Allocator>
1763typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v) {
1764 size_type __pos = __p - begin();
1765 size_type __to_end = size() - __pos;
1766 allocator_type& __a = __alloc();
1767 if (__pos < __to_end) { // insert by shifting things backward
1768 if (__front_spare() == 0)
1769 __add_front_capacity();
1770 // __front_spare() >= 1
1771 __annotate_increase_front(1);
1772 if (__pos == 0) {
1773 __alloc_traits::construct(__a, std::addressof(*--begin()), __v);
1774 --__start_;
1775 ++__size();
1776 } else {
1777 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
1778 iterator __b = begin();
1779 iterator __bm1 = std::prev(__b);
1780 if (__vt == pointer_traits<const_pointer>::pointer_to(*__b))
1781 __vt = pointer_traits<const_pointer>::pointer_to(*__bm1);
1782 __alloc_traits::construct(__a, std::addressof(*__bm1), std::move(*__b));
1783 --__start_;
1784 ++__size();
1785 if (__pos > 1)
1786 __b = __move_and_check(std::next(__b), __b + __pos, __b, __vt);
1787 *__b = *__vt;
1788 }
1789 } else { // insert by shifting things forward
1790 if (__back_spare() == 0)
1791 __add_back_capacity();
1792 // __back_capacity >= 1
1793 __annotate_increase_back(1);
1794 size_type __de = size() - __pos;
1795 if (__de == 0) {
1796 __alloc_traits::construct(__a, std::addressof(*end()), __v);
1797 ++__size();
1798 } else {
1799 const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
1800 iterator __e = end();
1801 iterator __em1 = std::prev(__e);
1802 if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1))
1803 __vt = pointer_traits<const_pointer>::pointer_to(*__e);
1804 __alloc_traits::construct(__a, std::addressof(*__e), std::move(*__em1));
1805 ++__size();
1806 if (__de > 1)
1807 __e = __move_backward_and_check(__e - __de, __em1, __e, __vt);
1808 *--__e = *__vt;
1809 }
1810 }
1811 return begin() + __pos;
1812}
1813
18141720template <class _Tp, class _Allocator>
18151721typename deque<_Tp, _Allocator>::iterator
18161722deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v) {
......@@ -1874,9 +1780,9 @@ template <class _Tp, class _Allocator>
18741780template <class _Iterator, class _Sentinel>
18751781_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator
18761782deque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) {
1877 __split_buffer<value_type, allocator_type&> __buf(__alloc());
1783 __split_buffer<value_type, allocator_type> __buf(__alloc());
18781784 __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l));
1879 typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
1785 typedef typename __split_buffer<value_type, allocator_type>::iterator __bi;
18801786 return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
18811787}
18821788
......@@ -1891,9 +1797,9 @@ template <class _Tp, class _Allocator>
18911797template <class _Iterator>
18921798_LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::iterator
18931799deque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) {
1894 __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc());
1895 __buf.__construct_at_end_with_size(__f, __n);
1896 typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd;
1800 __split_buffer<value_type, allocator_type> __buf(__n, 0, __alloc());
1801 __buf.__construct_at_end_with_size(std::move(__f), __n);
1802 typedef typename __split_buffer<value_type, allocator_type>::iterator __fwd;
18971803 return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end()));
18981804}
18991805
......@@ -2071,8 +1977,8 @@ void deque<_Tp, _Allocator>::__add_front_capacity() {
20711977 }
20721978 // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
20731979 else {
2074 __split_buffer<pointer, __pointer_allocator&> __buf(
2075 std::max<size_type>(2 * __map_.capacity(), 1), 0, __map_.__alloc_);
1980 __split_buffer<pointer, __pointer_allocator> __buf(
1981 std::max<size_type>(2 * __map_.capacity(), 1), 0, __map_.__get_allocator());
20761982
20771983 typedef __allocator_destructor<_Allocator> _Dp;
20781984 unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size));
......@@ -2081,10 +1987,7 @@ void deque<_Tp, _Allocator>::__add_front_capacity() {
20811987
20821988 for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i)
20831989 __buf.emplace_back(*__i);
2084 std::swap(__map_.__first_, __buf.__first_);
2085 std::swap(__map_.__begin_, __buf.__begin_);
2086 std::swap(__map_.__end_, __buf.__end_);
2087 std::swap(__map_.__cap_, __buf.__cap_);
1990 __map_.__swap_without_allocator(__buf);
20881991 __start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size;
20891992 }
20901993 __annotate_whole_block(0, __asan_poison);
......@@ -2134,34 +2037,26 @@ void deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) {
21342037 // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
21352038 else {
21362039 size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty();
2137 __split_buffer<pointer, __pointer_allocator&> __buf(
2138 std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 0, __map_.__alloc_);
2139# if _LIBCPP_HAS_EXCEPTIONS
2140 try {
2141# endif // _LIBCPP_HAS_EXCEPTIONS
2142 for (; __nb > 0; --__nb) {
2143 __buf.emplace_back(__alloc_traits::allocate(__a, __block_size));
2144 // ASan: this is empty container, we have to poison whole block
2145 __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size));
2146 }
2147# if _LIBCPP_HAS_EXCEPTIONS
2148 } catch (...) {
2040 __split_buffer<pointer, __pointer_allocator> __buf(
2041 std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 0, __map_.__get_allocator());
2042 auto __guard = std::__make_exception_guard([&] {
21492043 __annotate_delete();
21502044 for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i)
21512045 __alloc_traits::deallocate(__a, *__i, __block_size);
2152 throw;
2046 });
2047 for (; __nb > 0; --__nb) {
2048 __buf.emplace_back(__alloc_traits::allocate(__a, __block_size));
2049 // ASan: this is empty container, we have to poison whole block
2050 __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size));
21532051 }
2154# endif // _LIBCPP_HAS_EXCEPTIONS
2052 __guard.__complete();
21552053 for (; __back_capacity > 0; --__back_capacity) {
21562054 __buf.emplace_back(__map_.back());
21572055 __map_.pop_back();
21582056 }
21592057 for (__map_pointer __i = __map_.begin(); __i != __map_.end(); ++__i)
21602058 __buf.emplace_back(*__i);
2161 std::swap(__map_.__first_, __buf.__first_);
2162 std::swap(__map_.__begin_, __buf.__begin_);
2163 std::swap(__map_.__end_, __buf.__end_);
2164 std::swap(__map_.__cap_, __buf.__cap_);
2059 __map_.__swap_without_allocator(__buf);
21652060 __start_ += __ds;
21662061 }
21672062}
......@@ -2194,8 +2089,8 @@ void deque<_Tp, _Allocator>::__add_back_capacity() {
21942089 }
21952090 // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
21962091 else {
2197 __split_buffer<pointer, __pointer_allocator&> __buf(
2198 std::max<size_type>(2 * __map_.capacity(), 1), __map_.size(), __map_.__alloc_);
2092 __split_buffer<pointer, __pointer_allocator> __buf(
2093 std::max<size_type>(2 * __map_.capacity(), 1), __map_.size(), __map_.__get_allocator());
21992094
22002095 typedef __allocator_destructor<_Allocator> _Dp;
22012096 unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size));
......@@ -2204,10 +2099,7 @@ void deque<_Tp, _Allocator>::__add_back_capacity() {
22042099
22052100 for (__map_pointer __i = __map_.end(); __i != __map_.begin();)
22062101 __buf.emplace_front(*--__i);
2207 std::swap(__map_.__first_, __buf.__first_);
2208 std::swap(__map_.__begin_, __buf.__begin_);
2209 std::swap(__map_.__end_, __buf.__end_);
2210 std::swap(__map_.__cap_, __buf.__cap_);
2102 __map_.__swap_without_allocator(__buf);
22112103 __annotate_whole_block(__map_.size() - 1, __asan_poison);
22122104 }
22132105}
......@@ -2257,36 +2149,28 @@ void deque<_Tp, _Allocator>::__add_back_capacity(size_type __n) {
22572149 // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
22582150 else {
22592151 size_type __ds = __front_capacity * __block_size;
2260 __split_buffer<pointer, __pointer_allocator&> __buf(
2152 __split_buffer<pointer, __pointer_allocator> __buf(
22612153 std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()),
22622154 __map_.size() - __front_capacity,
2263 __map_.__alloc_);
2264# if _LIBCPP_HAS_EXCEPTIONS
2265 try {
2266# endif // _LIBCPP_HAS_EXCEPTIONS
2267 for (; __nb > 0; --__nb) {
2268 __buf.emplace_back(__alloc_traits::allocate(__a, __block_size));
2269 // ASan: this is an empty container, we have to poison the whole block
2270 __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size));
2271 }
2272# if _LIBCPP_HAS_EXCEPTIONS
2273 } catch (...) {
2155 __map_.__get_allocator());
2156 auto __guard = std::__make_exception_guard([&] {
22742157 __annotate_delete();
22752158 for (__map_pointer __i = __buf.begin(); __i != __buf.end(); ++__i)
22762159 __alloc_traits::deallocate(__a, *__i, __block_size);
2277 throw;
2160 });
2161 for (; __nb > 0; --__nb) {
2162 __buf.emplace_back(__alloc_traits::allocate(__a, __block_size));
2163 // ASan: this is an empty container, we have to poison the whole block
2164 __annotate_poison_block(std::__to_address(__buf.back()), std::__to_address(__buf.back() + __block_size));
22782165 }
2279# endif // _LIBCPP_HAS_EXCEPTIONS
2166 __guard.__complete();
22802167 for (; __front_capacity > 0; --__front_capacity) {
22812168 __buf.emplace_back(__map_.front());
22822169 __map_.pop_front();
22832170 }
22842171 for (__map_pointer __i = __map_.end(); __i != __map_.begin();)
22852172 __buf.emplace_front(*--__i);
2286 std::swap(__map_.__first_, __buf.__first_);
2287 std::swap(__map_.__begin_, __buf.__begin_);
2288 std::swap(__map_.__end_, __buf.__end_);
2289 std::swap(__map_.__cap_, __buf.__cap_);
2173 __map_.__swap_without_allocator(__buf);
22902174 __start_ -= __ds;
22912175 }
22922176}
lib/libcxx/include/errno.h+269-269
......@@ -23,381 +23,381 @@ Macros:
2323*/
2424
2525#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
26# include <__cxx03/errno.h>
26# include <__cxx03/__config>
2727#else
2828# include <__config>
29#endif
2930
30# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
31# pragma GCC system_header
32# endif
31#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
32# pragma GCC system_header
33#endif
3334
34# if __has_include_next(<errno.h>)
35# include_next <errno.h>
36# endif
35#if __has_include_next(<errno.h>)
36# include_next <errno.h>
37#endif
3738
38# ifdef __cplusplus
39#ifdef __cplusplus
3940
40# if !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)
41# if !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)
4142
42# ifdef ELAST
43# ifdef ELAST
4344
4445static const int __elast1 = ELAST + 1;
4546static const int __elast2 = ELAST + 2;
4647
47# else
48# else
4849
4950static const int __elast1 = 104;
5051static const int __elast2 = 105;
5152
52# endif
53# endif
5354
54# ifdef ENOTRECOVERABLE
55# ifdef ENOTRECOVERABLE
5556
56# define EOWNERDEAD __elast1
57# define EOWNERDEAD __elast1
5758
58# ifdef ELAST
59# undef ELAST
60# define ELAST EOWNERDEAD
61# endif
59# ifdef ELAST
60# undef ELAST
61# define ELAST EOWNERDEAD
62# endif
6263
63# elif defined(EOWNERDEAD)
64# elif defined(EOWNERDEAD)
6465
65# define ENOTRECOVERABLE __elast1
66# ifdef ELAST
67# undef ELAST
68# define ELAST ENOTRECOVERABLE
69# endif
66# define ENOTRECOVERABLE __elast1
67# ifdef ELAST
68# undef ELAST
69# define ELAST ENOTRECOVERABLE
70# endif
7071
71# else // defined(EOWNERDEAD)
72# else // defined(EOWNERDEAD)
7273
73# define EOWNERDEAD __elast1
74# define ENOTRECOVERABLE __elast2
75# ifdef ELAST
76# undef ELAST
77# define ELAST ENOTRECOVERABLE
78# endif
74# define EOWNERDEAD __elast1
75# define ENOTRECOVERABLE __elast2
76# ifdef ELAST
77# undef ELAST
78# define ELAST ENOTRECOVERABLE
79# endif
7980
80# endif // defined(EOWNERDEAD)
81# endif // defined(EOWNERDEAD)
8182
82# endif // !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)
83# endif // !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)
8384
8485// supply errno values likely to be missing, particularly on Windows
8586
86# ifndef EAFNOSUPPORT
87# define EAFNOSUPPORT 9901
88# endif
87# ifndef EAFNOSUPPORT
88# define EAFNOSUPPORT 9901
89# endif
8990
90# ifndef EADDRINUSE
91# define EADDRINUSE 9902
92# endif
91# ifndef EADDRINUSE
92# define EADDRINUSE 9902
93# endif
9394
94# ifndef EADDRNOTAVAIL
95# define EADDRNOTAVAIL 9903
96# endif
95# ifndef EADDRNOTAVAIL
96# define EADDRNOTAVAIL 9903
97# endif
9798
98# ifndef EISCONN
99# define EISCONN 9904
100# endif
99# ifndef EISCONN
100# define EISCONN 9904
101# endif
101102
102# ifndef EBADMSG
103# define EBADMSG 9905
104# endif
103# ifndef EBADMSG
104# define EBADMSG 9905
105# endif
105106
106# ifndef ECONNABORTED
107# define ECONNABORTED 9906
108# endif
107# ifndef ECONNABORTED
108# define ECONNABORTED 9906
109# endif
109110
110# ifndef EALREADY
111# define EALREADY 9907
112# endif
111# ifndef EALREADY
112# define EALREADY 9907
113# endif
113114
114# ifndef ECONNREFUSED
115# define ECONNREFUSED 9908
116# endif
115# ifndef ECONNREFUSED
116# define ECONNREFUSED 9908
117# endif
117118
118# ifndef ECONNRESET
119# define ECONNRESET 9909
120# endif
119# ifndef ECONNRESET
120# define ECONNRESET 9909
121# endif
121122
122# ifndef EDESTADDRREQ
123# define EDESTADDRREQ 9910
124# endif
123# ifndef EDESTADDRREQ
124# define EDESTADDRREQ 9910
125# endif
125126
126# ifndef EHOSTUNREACH
127# define EHOSTUNREACH 9911
128# endif
127# ifndef EHOSTUNREACH
128# define EHOSTUNREACH 9911
129# endif
129130
130# ifndef EIDRM
131# define EIDRM 9912
132# endif
131# ifndef EIDRM
132# define EIDRM 9912
133# endif
133134
134# ifndef EMSGSIZE
135# define EMSGSIZE 9913
136# endif
135# ifndef EMSGSIZE
136# define EMSGSIZE 9913
137# endif
137138
138# ifndef ENETDOWN
139# define ENETDOWN 9914
140# endif
139# ifndef ENETDOWN
140# define ENETDOWN 9914
141# endif
141142
142# ifndef ENETRESET
143# define ENETRESET 9915
144# endif
143# ifndef ENETRESET
144# define ENETRESET 9915
145# endif
145146
146# ifndef ENETUNREACH
147# define ENETUNREACH 9916
148# endif
147# ifndef ENETUNREACH
148# define ENETUNREACH 9916
149# endif
149150
150# ifndef ENOBUFS
151# define ENOBUFS 9917
152# endif
151# ifndef ENOBUFS
152# define ENOBUFS 9917
153# endif
153154
154# ifndef ENOLINK
155# define ENOLINK 9918
156# endif
155# ifndef ENOLINK
156# define ENOLINK 9918
157# endif
157158
158# ifndef ENODATA
159# define ENODATA 9919
160# endif
159# ifndef ENODATA
160# define ENODATA 9919
161# endif
161162
162# ifndef ENOMSG
163# define ENOMSG 9920
164# endif
163# ifndef ENOMSG
164# define ENOMSG 9920
165# endif
165166
166# ifndef ENOPROTOOPT
167# define ENOPROTOOPT 9921
168# endif
167# ifndef ENOPROTOOPT
168# define ENOPROTOOPT 9921
169# endif
169170
170# ifndef ENOSR
171# define ENOSR 9922
172# endif
171# ifndef ENOSR
172# define ENOSR 9922
173# endif
173174
174# ifndef ENOTSOCK
175# define ENOTSOCK 9923
176# endif
175# ifndef ENOTSOCK
176# define ENOTSOCK 9923
177# endif
177178
178# ifndef ENOSTR
179# define ENOSTR 9924
180# endif
179# ifndef ENOSTR
180# define ENOSTR 9924
181# endif
181182
182# ifndef ENOTCONN
183# define ENOTCONN 9925
184# endif
183# ifndef ENOTCONN
184# define ENOTCONN 9925
185# endif
185186
186# ifndef ENOTSUP
187# define ENOTSUP 9926
188# endif
187# ifndef ENOTSUP
188# define ENOTSUP 9926
189# endif
189190
190# ifndef ECANCELED
191# define ECANCELED 9927
192# endif
191# ifndef ECANCELED
192# define ECANCELED 9927
193# endif
193194
194# ifndef EINPROGRESS
195# define EINPROGRESS 9928
196# endif
195# ifndef EINPROGRESS
196# define EINPROGRESS 9928
197# endif
197198
198# ifndef EOPNOTSUPP
199# define EOPNOTSUPP 9929
200# endif
199# ifndef EOPNOTSUPP
200# define EOPNOTSUPP 9929
201# endif
201202
202# ifndef EWOULDBLOCK
203# define EWOULDBLOCK 9930
204# endif
203# ifndef EWOULDBLOCK
204# define EWOULDBLOCK 9930
205# endif
205206
206# ifndef EOWNERDEAD
207# define EOWNERDEAD 9931
208# endif
207# ifndef EOWNERDEAD
208# define EOWNERDEAD 9931
209# endif
209210
210# ifndef EPROTO
211# define EPROTO 9932
212# endif
211# ifndef EPROTO
212# define EPROTO 9932
213# endif
213214
214# ifndef EPROTONOSUPPORT
215# define EPROTONOSUPPORT 9933
216# endif
215# ifndef EPROTONOSUPPORT
216# define EPROTONOSUPPORT 9933
217# endif
217218
218# ifndef ENOTRECOVERABLE
219# define ENOTRECOVERABLE 9934
220# endif
219# ifndef ENOTRECOVERABLE
220# define ENOTRECOVERABLE 9934
221# endif
221222
222# ifndef ETIME
223# define ETIME 9935
224# endif
223# ifndef ETIME
224# define ETIME 9935
225# endif
225226
226# ifndef ETXTBSY
227# define ETXTBSY 9936
228# endif
227# ifndef ETXTBSY
228# define ETXTBSY 9936
229# endif
229230
230# ifndef ETIMEDOUT
231# define ETIMEDOUT 9938
232# endif
231# ifndef ETIMEDOUT
232# define ETIMEDOUT 9938
233# endif
233234
234# ifndef ELOOP
235# define ELOOP 9939
236# endif
235# ifndef ELOOP
236# define ELOOP 9939
237# endif
237238
238# ifndef EOVERFLOW
239# define EOVERFLOW 9940
240# endif
239# ifndef EOVERFLOW
240# define EOVERFLOW 9940
241# endif
241242
242# ifndef EPROTOTYPE
243# define EPROTOTYPE 9941
244# endif
243# ifndef EPROTOTYPE
244# define EPROTOTYPE 9941
245# endif
245246
246# ifndef ENOSYS
247# define ENOSYS 9942
248# endif
247# ifndef ENOSYS
248# define ENOSYS 9942
249# endif
249250
250# ifndef EINVAL
251# define EINVAL 9943
252# endif
251# ifndef EINVAL
252# define EINVAL 9943
253# endif
253254
254# ifndef ERANGE
255# define ERANGE 9944
256# endif
255# ifndef ERANGE
256# define ERANGE 9944
257# endif
257258
258# ifndef EILSEQ
259# define EILSEQ 9945
260# endif
259# ifndef EILSEQ
260# define EILSEQ 9945
261# endif
261262
262263// Windows Mobile doesn't appear to define these:
263264
264# ifndef E2BIG
265# define E2BIG 9946
266# endif
265# ifndef E2BIG
266# define E2BIG 9946
267# endif
267268
268# ifndef EDOM
269# define EDOM 9947
270# endif
269# ifndef EDOM
270# define EDOM 9947
271# endif
271272
272# ifndef EFAULT
273# define EFAULT 9948
274# endif
273# ifndef EFAULT
274# define EFAULT 9948
275# endif
275276
276# ifndef EBADF
277# define EBADF 9949
278# endif
277# ifndef EBADF
278# define EBADF 9949
279# endif
279280
280# ifndef EPIPE
281# define EPIPE 9950
282# endif
281# ifndef EPIPE
282# define EPIPE 9950
283# endif
283284
284# ifndef EXDEV
285# define EXDEV 9951
286# endif
285# ifndef EXDEV
286# define EXDEV 9951
287# endif
287288
288# ifndef EBUSY
289# define EBUSY 9952
290# endif
289# ifndef EBUSY
290# define EBUSY 9952
291# endif
291292
292# ifndef ENOTEMPTY
293# define ENOTEMPTY 9953
294# endif
293# ifndef ENOTEMPTY
294# define ENOTEMPTY 9953
295# endif
295296
296# ifndef ENOEXEC
297# define ENOEXEC 9954
298# endif
297# ifndef ENOEXEC
298# define ENOEXEC 9954
299# endif
299300
300# ifndef EEXIST
301# define EEXIST 9955
302# endif
301# ifndef EEXIST
302# define EEXIST 9955
303# endif
303304
304# ifndef EFBIG
305# define EFBIG 9956
306# endif
305# ifndef EFBIG
306# define EFBIG 9956
307# endif
307308
308# ifndef ENAMETOOLONG
309# define ENAMETOOLONG 9957
310# endif
309# ifndef ENAMETOOLONG
310# define ENAMETOOLONG 9957
311# endif
311312
312# ifndef ENOTTY
313# define ENOTTY 9958
314# endif
313# ifndef ENOTTY
314# define ENOTTY 9958
315# endif
315316
316# ifndef EINTR
317# define EINTR 9959
318# endif
317# ifndef EINTR
318# define EINTR 9959
319# endif
319320
320# ifndef ESPIPE
321# define ESPIPE 9960
322# endif
321# ifndef ESPIPE
322# define ESPIPE 9960
323# endif
323324
324# ifndef EIO
325# define EIO 9961
326# endif
325# ifndef EIO
326# define EIO 9961
327# endif
327328
328# ifndef EISDIR
329# define EISDIR 9962
330# endif
329# ifndef EISDIR
330# define EISDIR 9962
331# endif
331332
332# ifndef ECHILD
333# define ECHILD 9963
334# endif
333# ifndef ECHILD
334# define ECHILD 9963
335# endif
335336
336# ifndef ENOLCK
337# define ENOLCK 9964
338# endif
337# ifndef ENOLCK
338# define ENOLCK 9964
339# endif
339340
340# ifndef ENOSPC
341# define ENOSPC 9965
342# endif
341# ifndef ENOSPC
342# define ENOSPC 9965
343# endif
343344
344# ifndef ENXIO
345# define ENXIO 9966
346# endif
345# ifndef ENXIO
346# define ENXIO 9966
347# endif
347348
348# ifndef ENODEV
349# define ENODEV 9967
350# endif
349# ifndef ENODEV
350# define ENODEV 9967
351# endif
351352
352# ifndef ENOENT
353# define ENOENT 9968
354# endif
353# ifndef ENOENT
354# define ENOENT 9968
355# endif
355356
356# ifndef ESRCH
357# define ESRCH 9969
358# endif
357# ifndef ESRCH
358# define ESRCH 9969
359# endif
359360
360# ifndef ENOTDIR
361# define ENOTDIR 9970
362# endif
361# ifndef ENOTDIR
362# define ENOTDIR 9970
363# endif
363364
364# ifndef ENOMEM
365# define ENOMEM 9971
366# endif
365# ifndef ENOMEM
366# define ENOMEM 9971
367# endif
367368
368# ifndef EPERM
369# define EPERM 9972
370# endif
369# ifndef EPERM
370# define EPERM 9972
371# endif
371372
372# ifndef EACCES
373# define EACCES 9973
374# endif
373# ifndef EACCES
374# define EACCES 9973
375# endif
375376
376# ifndef EROFS
377# define EROFS 9974
378# endif
377# ifndef EROFS
378# define EROFS 9974
379# endif
379380
380# ifndef EDEADLK
381# define EDEADLK 9975
382# endif
381# ifndef EDEADLK
382# define EDEADLK 9975
383# endif
383384
384# ifndef EAGAIN
385# define EAGAIN 9976
386# endif
385# ifndef EAGAIN
386# define EAGAIN 9976
387# endif
387388
388# ifndef ENFILE
389# define ENFILE 9977
390# endif
389# ifndef ENFILE
390# define ENFILE 9977
391# endif
391392
392# ifndef EMFILE
393# define EMFILE 9978
394# endif
393# ifndef EMFILE
394# define EMFILE 9978
395# endif
395396
396# ifndef EMLINK
397# define EMLINK 9979
398# endif
397# ifndef EMLINK
398# define EMLINK 9979
399# endif
399400
400# endif // __cplusplus
401#endif // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
401#endif // __cplusplus
402402
403403#endif // _LIBCPP_ERRNO_H
lib/libcxx/include/exception+4-1
......@@ -93,10 +93,13 @@ template <class E> void rethrow_if_nested(const E& e);
9393
9494# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
9595# include <cstddef>
96# include <cstdlib>
9796# include <new>
9897# include <type_traits>
9998# endif
99
100# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23
101# include <cstdlib>
102# endif
100103#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
101104
102105#endif // _LIBCPP_EXCEPTION
lib/libcxx/include/ext/hash_map+7-48
......@@ -206,6 +206,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
206206#else
207207# include <__config>
208208# include <__hash_table>
209# include <__memory/compressed_pair.h>
209210# include <algorithm>
210211# include <ext/__hash>
211212# include <functional>
......@@ -224,21 +225,9 @@ _LIBCPP_WARNING("Use of the header <ext/hash_map> is deprecated. Migrate to <un
224225
225226namespace __gnu_cxx {
226227
227template <class _Tp, class _Hash, bool = std::is_empty<_Hash>::value && !std::__libcpp_is_final<_Hash>::value >
228class __hash_map_hasher : private _Hash {
229public:
230 _LIBCPP_HIDE_FROM_ABI __hash_map_hasher() : _Hash() {}
231 _LIBCPP_HIDE_FROM_ABI __hash_map_hasher(const _Hash& __h) : _Hash(__h) {}
232 _LIBCPP_HIDE_FROM_ABI const _Hash& hash_function() const { return *this; }
233 _LIBCPP_HIDE_FROM_ABI size_t operator()(const _Tp& __x) const { return static_cast<const _Hash&>(*this)(__x.first); }
234 _LIBCPP_HIDE_FROM_ABI size_t operator()(const typename _Tp::first_type& __x) const {
235 return static_cast<const _Hash&>(*this)(__x);
236 }
237};
238
239228template <class _Tp, class _Hash>
240class __hash_map_hasher<_Tp, _Hash, false> {
241 _Hash __hash_;
229class __hash_map_hasher {
230 _LIBCPP_COMPRESSED_ELEMENT(_Hash, __hash_);
242231
243232public:
244233 _LIBCPP_HIDE_FROM_ABI __hash_map_hasher() : __hash_() {}
......@@ -248,30 +237,9 @@ public:
248237 _LIBCPP_HIDE_FROM_ABI size_t operator()(const typename _Tp::first_type& __x) const { return __hash_(__x); }
249238};
250239
251template <class _Tp, class _Pred, bool = std::is_empty<_Pred>::value && !std::__libcpp_is_final<_Pred>::value >
252class __hash_map_equal : private _Pred {
253public:
254 _LIBCPP_HIDE_FROM_ABI __hash_map_equal() : _Pred() {}
255 _LIBCPP_HIDE_FROM_ABI __hash_map_equal(const _Pred& __p) : _Pred(__p) {}
256 _LIBCPP_HIDE_FROM_ABI const _Pred& key_eq() const { return *this; }
257 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
258 return static_cast<const _Pred&>(*this)(__x.first, __y.first);
259 }
260 _LIBCPP_HIDE_FROM_ABI bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const {
261 return static_cast<const _Pred&>(*this)(__x, __y.first);
262 }
263 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const {
264 return static_cast<const _Pred&>(*this)(__x.first, __y);
265 }
266 _LIBCPP_HIDE_FROM_ABI bool
267 operator()(const typename _Tp::first_type& __x, const typename _Tp::first_type& __y) const {
268 return static_cast<const _Pred&>(*this)(__x, __y);
269 }
270};
271
272240template <class _Tp, class _Pred>
273class __hash_map_equal<_Tp, _Pred, false> {
274 _Pred __pred_;
241class __hash_map_equal {
242 _LIBCPP_COMPRESSED_ELEMENT(_Pred, __pred_);
275243
276244public:
277245 _LIBCPP_HIDE_FROM_ABI __hash_map_equal() : __pred_() {}
......@@ -467,8 +435,6 @@ private:
467435
468436 __table __table_;
469437
470 typedef typename __table::__node_pointer __node_pointer;
471 typedef typename __table::__node_const_pointer __node_const_pointer;
472438 typedef typename __table::__node_traits __node_traits;
473439 typedef typename __table::__node_allocator __node_allocator;
474440 typedef typename __table::__node __node;
......@@ -604,10 +570,7 @@ hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
604570}
605571
606572template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
607hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(const hash_map& __u) : __table_(__u.__table_) {
608 __table_.__rehash_unique(__u.bucket_count());
609 insert(__u.begin(), __u.end());
610}
573hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(const hash_map& __u) : __table_(__u.__table_) {}
611574
612575template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
613576typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
......@@ -693,7 +656,6 @@ private:
693656
694657 __table __table_;
695658
696 typedef typename __table::__node_traits __node_traits;
697659 typedef typename __table::__node_allocator __node_allocator;
698660 typedef typename __table::__node __node;
699661 typedef __hash_map_node_destructor<__node_allocator> _Dp;
......@@ -822,10 +784,7 @@ hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
822784}
823785
824786template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
825hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(const hash_multimap& __u) : __table_(__u.__table_) {
826 __table_.__rehash_multi(__u.bucket_count());
827 insert(__u.begin(), __u.end());
828}
787hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(const hash_multimap& __u) : __table_(__u.__table_) {}
829788
830789template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
831790template <class _InputIterator>
lib/libcxx/include/ext/hash_set+2-8
......@@ -356,10 +356,7 @@ hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
356356}
357357
358358template <class _Value, class _Hash, class _Pred, class _Alloc>
359hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(const hash_set& __u) : __table_(__u.__table_) {
360 __table_.__rehash_unique(__u.bucket_count());
361 insert(__u.begin(), __u.end());
362}
359hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(const hash_set& __u) : __table_(__u.__table_) {}
363360
364361template <class _Value, class _Hash, class _Pred, class _Alloc>
365362template <class _InputIterator>
......@@ -534,10 +531,7 @@ hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
534531}
535532
536533template <class _Value, class _Hash, class _Pred, class _Alloc>
537hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(const hash_multiset& __u) : __table_(__u.__table_) {
538 __table_.__rehash_multi(__u.bucket_count());
539 insert(__u.begin(), __u.end());
540}
534hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(const hash_multiset& __u) : __table_(__u.__table_) {}
541535
542536template <class _Value, class _Hash, class _Pred, class _Alloc>
543537template <class _InputIterator>
lib/libcxx/include/fenv.h+43-43
......@@ -50,69 +50,69 @@ int feupdateenv(const fenv_t* envp);
5050*/
5151
5252#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
53# include <__cxx03/fenv.h>
53# include <__cxx03/__config>
5454#else
5555# include <__config>
56#endif
5657
57# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
58# pragma GCC system_header
59# endif
58#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
59# pragma GCC system_header
60#endif
6061
61# if __has_include_next(<fenv.h>)
62# include_next <fenv.h>
63# endif
62#if __has_include_next(<fenv.h>)
63# include_next <fenv.h>
64#endif
6465
65# ifdef __cplusplus
66#ifdef __cplusplus
6667
6768extern "C++" {
6869
69# ifdef feclearexcept
70# undef feclearexcept
71# endif
70# ifdef feclearexcept
71# undef feclearexcept
72# endif
7273
73# ifdef fegetexceptflag
74# undef fegetexceptflag
75# endif
74# ifdef fegetexceptflag
75# undef fegetexceptflag
76# endif
7677
77# ifdef feraiseexcept
78# undef feraiseexcept
79# endif
78# ifdef feraiseexcept
79# undef feraiseexcept
80# endif
8081
81# ifdef fesetexceptflag
82# undef fesetexceptflag
83# endif
82# ifdef fesetexceptflag
83# undef fesetexceptflag
84# endif
8485
85# ifdef fetestexcept
86# undef fetestexcept
87# endif
86# ifdef fetestexcept
87# undef fetestexcept
88# endif
8889
89# ifdef fegetround
90# undef fegetround
91# endif
90# ifdef fegetround
91# undef fegetround
92# endif
9293
93# ifdef fesetround
94# undef fesetround
95# endif
94# ifdef fesetround
95# undef fesetround
96# endif
9697
97# ifdef fegetenv
98# undef fegetenv
99# endif
98# ifdef fegetenv
99# undef fegetenv
100# endif
100101
101# ifdef feholdexcept
102# undef feholdexcept
103# endif
102# ifdef feholdexcept
103# undef feholdexcept
104# endif
104105
105# ifdef fesetenv
106# undef fesetenv
107# endif
106# ifdef fesetenv
107# undef fesetenv
108# endif
108109
109# ifdef feupdateenv
110# undef feupdateenv
111# endif
110# ifdef feupdateenv
111# undef feupdateenv
112# endif
112113
113114} // extern "C++"
114115
115# endif // defined(__cplusplus)
116#endif // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
116#endif // defined(__cplusplus)
117117
118118#endif // _LIBCPP_FENV_H
lib/libcxx/include/flat_map+663-11
......@@ -17,18 +17,359 @@
1717#include <initializer_list> // see [initializer.list.syn]
1818
1919namespace std {
20 struct sorted_unique_t { explicit sorted_unique_t() = default; };
21 inline constexpr sorted_unique_t sorted_unique{};
22
2023 // [flat.map], class template flat_map
2124 template<class Key, class T, class Compare = less<Key>,
2225 class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
23 class flat_map;
26 class flat_map {
27 public:
28 // types
29 using key_type = Key;
30 using mapped_type = T;
31 using value_type = pair<key_type, mapped_type>;
32 using key_compare = Compare;
33 using reference = pair<const key_type&, mapped_type&>;
34 using const_reference = pair<const key_type&, const mapped_type&>;
35 using size_type = size_t;
36 using difference_type = ptrdiff_t;
37 using iterator = implementation-defined; // see [container.requirements]
38 using const_iterator = implementation-defined; // see [container.requirements]
39 using reverse_iterator = std::reverse_iterator<iterator>;
40 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
41 using key_container_type = KeyContainer;
42 using mapped_container_type = MappedContainer;
2443
25 struct sorted_unique_t { explicit sorted_unique_t() = default; };
26 inline constexpr sorted_unique_t sorted_unique{};
44 class value_compare {
45 private:
46 key_compare comp; // exposition only
47 constexpr value_compare(key_compare c) : comp(c) { } // exposition only
48
49 public:
50 constexpr bool operator()(const_reference x, const_reference y) const {
51 return comp(x.first, y.first);
52 }
53 };
54
55 struct containers {
56 key_container_type keys;
57 mapped_container_type values;
58 };
59
60 // [flat.map.cons], constructors
61 constexpr flat_map() : flat_map(key_compare()) { }
62
63 constexpr flat_map(const flat_map&);
64 constexpr flat_map(flat_map&&);
65 constexpr flat_map& operator=(const flat_map&);
66 constexpr flat_map& operator=(flat_map&&);
67
68 constexpr explicit flat_map(const key_compare& comp)
69 : c(), compare(comp) { }
70
71 constexpr flat_map(key_container_type key_cont, mapped_container_type mapped_cont,
72 const key_compare& comp = key_compare());
73
74 constexpr flat_map(sorted_unique_t, key_container_type key_cont,
75 mapped_container_type mapped_cont,
76 const key_compare& comp = key_compare());
77
78 template<class InputIterator>
79 constexpr flat_map(InputIterator first, InputIterator last,
80 const key_compare& comp = key_compare())
81 : c(), compare(comp) { insert(first, last); }
82
83 template<class InputIterator>
84 constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last,
85 const key_compare& comp = key_compare())
86 : c(), compare(comp) { insert(sorted_unique, first, last); }
87
88 template<container-compatible-range<value_type> R>
89 constexpr flat_map(from_range_t, R&& rg)
90 : flat_map(from_range, std::forward<R>(rg), key_compare()) { }
91 template<container-compatible-range<value_type> R>
92 constexpr flat_map(from_range_t, R&& rg, const key_compare& comp)
93 : flat_map(comp) { insert_range(std::forward<R>(rg)); }
94
95 constexpr flat_map(initializer_list<value_type> il, const key_compare& comp = key_compare())
96 : flat_map(il.begin(), il.end(), comp) { }
97
98 constexpr flat_map(sorted_unique_t, initializer_list<value_type> il,
99 const key_compare& comp = key_compare())
100 : flat_map(sorted_unique, il.begin(), il.end(), comp) { }
101
102 // [flat.map.cons.alloc], constructors with allocators
103
104 template<class Alloc>
105 constexpr explicit flat_map(const Alloc& a);
106 template<class Alloc>
107 constexpr flat_map(const key_compare& comp, const Alloc& a);
108 template<class Alloc>
109 constexpr flat_map(const key_container_type& key_cont,
110 const mapped_container_type& mapped_cont,
111 const Alloc& a);
112 template<class Alloc>
113 constexpr flat_map(const key_container_type& key_cont,
114 const mapped_container_type& mapped_cont,
115 const key_compare& comp, const Alloc& a);
116 template<class Alloc>
117 constexpr flat_map(sorted_unique_t, const key_container_type& key_cont,
118 const mapped_container_type& mapped_cont, const Alloc& a);
119 template<class Alloc>
120 constexpr flat_map(sorted_unique_t, const key_container_type& key_cont,
121 const mapped_container_type& mapped_cont, const key_compare& comp,
122 const Alloc& a);
123 template<class Alloc>
124 constexpr flat_map(const flat_map&, const Alloc& a);
125 template<class Alloc>
126 constexpr flat_map(flat_map&&, const Alloc& a);
127 template<class InputIterator, class Alloc>
128 constexpr flat_map(InputIterator first, InputIterator last, const Alloc& a);
129 template<class InputIterator, class Alloc>
130 constexpr flat_map(InputIterator first, InputIterator last,
131 const key_compare& comp, const Alloc& a);
132 template<class InputIterator, class Alloc>
133 constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last,
134 const Alloc& a);
135 template<class InputIterator, class Alloc>
136 constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last,
137 const key_compare& comp, const Alloc& a);
138 template<container-compatible-range<value_type> R, class Alloc>
139 constexpr flat_map(from_range_t, R&& rg, const Alloc& a);
140 template<container-compatible-range<value_type> R, class Alloc>
141 constexpr flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
142 template<class Alloc>
143 constexpr flat_map(initializer_list<value_type> il, const Alloc& a);
144 template<class Alloc>
145 constexpr flat_map(initializer_list<value_type> il, const key_compare& comp,
146 const Alloc& a);
147 template<class Alloc>
148 constexpr flat_map(sorted_unique_t, initializer_list<value_type> il, const Alloc& a);
149 template<class Alloc>
150 constexpr flat_map(sorted_unique_t, initializer_list<value_type> il,
151 const key_compare& comp, const Alloc& a);
152
153 constexpr flat_map& operator=(initializer_list<value_type>);
154
155 // iterators
156 constexpr iterator begin() noexcept;
157 constexpr const_iterator begin() const noexcept;
158 constexpr iterator end() noexcept;
159 constexpr const_iterator end() const noexcept;
160
161 constexpr reverse_iterator rbegin() noexcept;
162 constexpr const_reverse_iterator rbegin() const noexcept;
163 constexpr reverse_iterator rend() noexcept;
164 constexpr const_reverse_iterator rend() const noexcept;
165
166 constexpr const_iterator cbegin() const noexcept;
167 constexpr const_iterator cend() const noexcept;
168 constexpr const_reverse_iterator crbegin() const noexcept;
169 constexpr const_reverse_iterator crend() const noexcept;
170
171 // [flat.map.capacity], capacity
172 constexpr bool empty() const noexcept;
173 constexpr size_type size() const noexcept;
174 constexpr size_type max_size() const noexcept;
175
176 // [flat.map.access], element access
177 constexpr mapped_type& operator[](const key_type& x);
178 constexpr mapped_type& operator[](key_type&& x);
179 template<class K> constexpr mapped_type& operator[](K&& x);
180 constexpr mapped_type& at(const key_type& x);
181 constexpr const mapped_type& at(const key_type& x) const;
182 template<class K> constexpr mapped_type& at(const K& x);
183 template<class K> constexpr const mapped_type& at(const K& x) const;
184
185 // [flat.map.modifiers], modifiers
186 template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args);
187 template<class... Args>
188 constexpr iterator emplace_hint(const_iterator position, Args&&... args);
189
190 constexpr pair<iterator, bool> insert(const value_type& x)
191 { return emplace(x); }
192 constexpr pair<iterator, bool> insert(value_type&& x)
193 { return emplace(std::move(x)); }
194 constexpr iterator insert(const_iterator position, const value_type& x)
195 { return emplace_hint(position, x); }
196 constexpr iterator insert(const_iterator position, value_type&& x)
197 { return emplace_hint(position, std::move(x)); }
198
199 template<class P> constexpr pair<iterator, bool> insert(P&& x);
200 template<class P>
201 constexpr iterator insert(const_iterator position, P&&);
202 template<class InputIterator>
203 constexpr void insert(InputIterator first, InputIterator last);
204 template<class InputIterator>
205 constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last);
206 template<container-compatible-range<value_type> R>
207 constexpr void insert_range(R&& rg);
208 template<container-compatible-range<value_type> R>
209 constexpr void insert_range(sorted_unique_t, R&& rg);
210
211 constexpr void insert(initializer_list<value_type> il)
212 { insert(il.begin(), il.end()); }
213 constexpr void insert(sorted_unique_t, initializer_list<value_type> il)
214 { insert(sorted_unique, il.begin(), il.end()); }
215
216 constexpr containers extract() &&;
217 constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
218
219 template<class... Args>
220 constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
221 template<class... Args>
222 constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
223 template<class K, class... Args>
224 constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args);
225 template<class... Args>
226 constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
227 template<class... Args>
228 constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
229 template<class K, class... Args>
230 constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
231 template<class M>
232 constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
233 template<class M>
234 constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
235 template<class K, class M>
236 constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
237 template<class M>
238 constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
239 template<class M>
240 constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
241 template<class K, class M>
242 constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
243
244 constexpr iterator erase(iterator position);
245 constexpr iterator erase(const_iterator position);
246 constexpr size_type erase(const key_type& x);
247 template<class K> constexpr size_type erase(K&& x);
248 constexpr iterator erase(const_iterator first, const_iterator last);
249
250 constexpr void swap(flat_map& y) noexcept(see below);
251 constexpr void clear() noexcept;
252
253 // observers
254 constexpr key_compare key_comp() const;
255 constexpr value_compare value_comp() const;
256
257 constexpr const key_container_type& keys() const noexcept { return c.keys; }
258 constexpr const mapped_container_type& values() const noexcept { return c.values; }
259
260 // map operations
261 constexpr iterator find(const key_type& x);
262 constexpr const_iterator find(const key_type& x) const;
263 template<class K> constexpr iterator find(const K& x);
264 template<class K> constexpr const_iterator find(const K& x) const;
265
266 constexpr size_type count(const key_type& x) const;
267 template<class K> constexpr size_type count(const K& x) const;
268
269 constexpr bool contains(const key_type& x) const;
270 template<class K> constexpr bool contains(const K& x) const;
271
272 constexpr iterator lower_bound(const key_type& x);
273 constexpr const_iterator lower_bound(const key_type& x) const;
274 template<class K> constexpr iterator lower_bound(const K& x);
275 template<class K> constexpr const_iterator lower_bound(const K& x) const;
276
277 constexpr iterator upper_bound(const key_type& x);
278 constexpr const_iterator upper_bound(const key_type& x) const;
279 template<class K> constexpr iterator upper_bound(const K& x);
280 template<class K> constexpr const_iterator upper_bound(const K& x) const;
281
282 constexpr pair<iterator, iterator> equal_range(const key_type& x);
283 constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
284 template<class K> constexpr pair<iterator, iterator> equal_range(const K& x);
285 template<class K>
286 constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const;
287
288 friend constexpr bool operator==(const flat_map& x, const flat_map& y);
289
290 friend constexpr synth-three-way-result<value_type>
291 operator<=>(const flat_map& x, const flat_map& y);
292
293 friend constexpr void swap(flat_map& x, flat_map& y) noexcept(noexcept(x.swap(y)))
294 { x.swap(y); }
295
296 private:
297 containers c; // exposition only
298 key_compare compare; // exposition only
299
300 struct key-equiv { // exposition only
301 constexpr key-equiv(key_compare c) : comp(c) { }
302 constexpr bool operator()(const_reference x, const_reference y) const {
303 return !comp(x.first, y.first) && !comp(y.first, x.first);
304 }
305 key_compare comp;
306 };
307 };
308
309 template<class KeyContainer, class MappedContainer,
310 class Compare = less<typename KeyContainer::value_type>>
311 flat_map(KeyContainer, MappedContainer, Compare = Compare())
312 -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
313 Compare, KeyContainer, MappedContainer>;
314
315 template<class KeyContainer, class MappedContainer, class Allocator>
316 flat_map(KeyContainer, MappedContainer, Allocator)
317 -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
318 less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>;
319 template<class KeyContainer, class MappedContainer, class Compare, class Allocator>
320 flat_map(KeyContainer, MappedContainer, Compare, Allocator)
321 -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
322 Compare, KeyContainer, MappedContainer>;
323
324 template<class KeyContainer, class MappedContainer,
325 class Compare = less<typename KeyContainer::value_type>>
326 flat_map(sorted_unique_t, KeyContainer, MappedContainer, Compare = Compare())
327 -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
328 Compare, KeyContainer, MappedContainer>;
329
330 template<class KeyContainer, class MappedContainer, class Allocator>
331 flat_map(sorted_unique_t, KeyContainer, MappedContainer, Allocator)
332 -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
333 less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>;
334 template<class KeyContainer, class MappedContainer, class Compare, class Allocator>
335 flat_map(sorted_unique_t, KeyContainer, MappedContainer, Compare, Allocator)
336 -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
337 Compare, KeyContainer, MappedContainer>;
338
339 template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>>
340 flat_map(InputIterator, InputIterator, Compare = Compare())
341 -> flat_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare>;
342
343 template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>>
344 flat_map(sorted_unique_t, InputIterator, InputIterator, Compare = Compare())
345 -> flat_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare>;
346
347 template<ranges::input_range R, class Compare = less<range-key-type<R>>,
348 class Allocator = allocator<byte>>
349 flat_map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
350 -> flat_map<range-key-type<R>, range-mapped-type<R>, Compare,
351 vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>>,
352 vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>>;
353
354 template<ranges::input_range R, class Allocator>
355 flat_map(from_range_t, R&&, Allocator)
356 -> flat_map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>,
357 vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>>,
358 vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>>;
359
360 template<class Key, class T, class Compare = less<Key>>
361 flat_map(initializer_list<pair<Key, T>>, Compare = Compare())
362 -> flat_map<Key, T, Compare>;
363
364 template<class Key, class T, class Compare = less<Key>>
365 flat_map(sorted_unique_t, initializer_list<pair<Key, T>>, Compare = Compare())
366 -> flat_map<Key, T, Compare>;
27367
28368 template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
29 class Allocator>
30 struct uses_allocator<flat_map<Key, T, Compare, KeyContainer, MappedContainer>,
31 Allocator>;
369 class Allocator>
370 struct uses_allocator<flat_map<Key, T, Compare, KeyContainer, MappedContainer>, Allocator>
371 : bool_constant<uses_allocator_v<KeyContainer, Allocator> &&
372 uses_allocator_v<MappedContainer, Allocator>> { };
32373
33374 // [flat.map.erasure], erasure for flat_map
34375 template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
......@@ -36,18 +377,329 @@ namespace std {
36377 typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type
37378 erase_if(flat_map<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
38379
380 struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
381 inline constexpr sorted_equivalent_t sorted_equivalent{};
382
39383 // [flat.multimap], class template flat_multimap
40384 template<class Key, class T, class Compare = less<Key>,
41385 class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
42 class flat_multimap;
386 class flat_multimap {
387 public:
388 // types
389 using key_type = Key;
390 using mapped_type = T;
391 using value_type = pair<key_type, mapped_type>;
392 using key_compare = Compare;
393 using reference = pair<const key_type&, mapped_type&>;
394 using const_reference = pair<const key_type&, const mapped_type&>;
395 using size_type = size_t;
396 using difference_type = ptrdiff_t;
397 using iterator = implementation-defined; // see [container.requirements]
398 using const_iterator = implementation-defined; // see [container.requirements]
399 using reverse_iterator = std::reverse_iterator<iterator>;
400 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
401 using key_container_type = KeyContainer;
402 using mapped_container_type = MappedContainer;
43403
44 struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
45 inline constexpr sorted_equivalent_t sorted_equivalent{};
404 class value_compare {
405 private:
406 key_compare comp; // exposition only
407 constexpr value_compare(key_compare c) : comp(c) { } // exposition only
408
409 public:
410 constexpr bool operator()(const_reference x, const_reference y) const {
411 return comp(x.first, y.first);
412 }
413 };
414
415 struct containers {
416 key_container_type keys;
417 mapped_container_type values;
418 };
419
420 // [flat.multimap.cons], constructors
421 constexpr flat_multimap() : flat_multimap(key_compare()) { }
422
423 constexpr flat_multimap(const flat_multimap&);
424 constexpr flat_multimap(flat_multimap&&);
425 constexpr flat_multimap& operator=(const flat_multimap&);
426 constexpr flat_multimap& operator=(flat_multimap&&);
427
428 constexpr explicit flat_multimap(const key_compare& comp)
429 : c(), compare(comp) { }
430
431 constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont,
432 const key_compare& comp = key_compare());
433
434 constexpr flat_multimap(sorted_equivalent_t,
435 key_container_type key_cont, mapped_container_type mapped_cont,
436 const key_compare& comp = key_compare());
437
438 template<class InputIterator>
439 constexpr flat_multimap(InputIterator first, InputIterator last,
440 const key_compare& comp = key_compare())
441 : c(), compare(comp)
442 { insert(first, last); }
443
444 template<class InputIterator>
445 constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
446 const key_compare& comp = key_compare())
447 : c(), compare(comp) { insert(sorted_equivalent, first, last); }
448
449 template<container-compatible-range<value_type> R>
450 constexpr flat_multimap(from_range_t, R&& rg)
451 : flat_multimap(from_range, std::forward<R>(rg), key_compare()) { }
452 template<container-compatible-range<value_type> R>
453 constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp)
454 : flat_multimap(comp) { insert_range(std::forward<R>(rg)); }
455
456 constexpr flat_multimap(initializer_list<value_type> il,
457 const key_compare& comp = key_compare())
458 : flat_multimap(il.begin(), il.end(), comp) { }
459
460 constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
461 const key_compare& comp = key_compare())
462 : flat_multimap(sorted_equivalent, il.begin(), il.end(), comp) { }
463
464 // [flat.multimap.cons.alloc], constructors with allocators
465
466 template<class Alloc>
467 constexpr explicit flat_multimap(const Alloc& a);
468 template<class Alloc>
469 constexpr flat_multimap(const key_compare& comp, const Alloc& a);
470 template<class Alloc>
471 constexpr flat_multimap(const key_container_type& key_cont,
472 const mapped_container_type& mapped_cont, const Alloc& a);
473 template<class Alloc>
474 constexpr flat_multimap(const key_container_type& key_cont,
475 const mapped_container_type& mapped_cont,
476 const key_compare& comp, const Alloc& a);
477 template<class Alloc>
478 constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
479 const mapped_container_type& mapped_cont, const Alloc& a);
480 template<class Alloc>
481 constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
482 const mapped_container_type& mapped_cont,
483 const key_compare& comp, const Alloc& a);
484 template<class Alloc>
485 constexpr flat_multimap(const flat_multimap&, const Alloc& a);
486 template<class Alloc>
487 constexpr flat_multimap(flat_multimap&&, const Alloc& a);
488 template<class InputIterator, class Alloc>
489 constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a);
490 template<class InputIterator, class Alloc>
491 constexpr flat_multimap(InputIterator first, InputIterator last,
492 const key_compare& comp, const Alloc& a);
493 template<class InputIterator, class Alloc>
494 constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
495 const Alloc& a);
496 template<class InputIterator, class Alloc>
497 constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
498 const key_compare& comp, const Alloc& a);
499 template<container-compatible-range<value_type> R, class Alloc>
500 constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a);
501 template<container-compatible-range<value_type> R, class Alloc>
502 constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
503 template<class Alloc>
504 constexpr flat_multimap(initializer_list<value_type> il, const Alloc& a);
505 template<class Alloc>
506 constexpr flat_multimap(initializer_list<value_type> il, const key_compare& comp,
507 const Alloc& a);
508 template<class Alloc>
509 constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
510 const Alloc& a);
511 template<class Alloc>
512 constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
513 const key_compare& comp, const Alloc& a);
514
515 flat_multimap& operator=(initializer_list<value_type>);
516
517 // iterators
518 constexpr iterator begin() noexcept;
519 constexpr const_iterator begin() const noexcept;
520 constexpr iterator end() noexcept;
521 constexpr const_iterator end() const noexcept;
522
523 constexpr reverse_iterator rbegin() noexcept;
524 constexpr const_reverse_iterator rbegin() const noexcept;
525 constexpr reverse_iterator rend() noexcept;
526 constexpr const_reverse_iterator rend() const noexcept;
527
528 constexpr const_iterator cbegin() const noexcept;
529 constexpr const_iterator cend() const noexcept;
530 constexpr const_reverse_iterator crbegin() const noexcept;
531 constexpr const_reverse_iterator crend() const noexcept;
532
533 // capacity
534 constexpr bool empty() const noexcept;
535 constexpr size_type size() const noexcept;
536 constexpr size_type max_size() const noexcept;
537
538 // modifiers
539 template<class... Args> constexpr iterator emplace(Args&&... args);
540 template<class... Args>
541 constexpr iterator emplace_hint(const_iterator position, Args&&... args);
542
543 constexpr iterator insert(const value_type& x)
544 { return emplace(x); }
545 constexpr iterator insert(value_type&& x)
546 { return emplace(std::move(x)); }
547 constexpr iterator insert(const_iterator position, const value_type& x)
548 { return emplace_hint(position, x); }
549 constexpr iterator insert(const_iterator position, value_type&& x)
550 { return emplace_hint(position, std::move(x)); }
551
552 template<class P> constexpr iterator insert(P&& x);
553 template<class P>
554 constexpr iterator insert(const_iterator position, P&&);
555 template<class InputIterator>
556 constexpr void insert(InputIterator first, InputIterator last);
557 template<class InputIterator>
558 constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
559 template<container-compatible-range<value_type> R>
560 constexpr void insert_range(R&& rg);
561 template<container-compatible-range<value_type> R>
562 constexpr void insert_range(sorted_equivalent_t, R&& rg);
563
564 constexpr void insert(initializer_list<value_type> il)
565 { insert(il.begin(), il.end()); }
566 constexpr void insert(sorted_equivalent_t, initializer_list<value_type> il)
567 { insert(sorted_equivalent, il.begin(), il.end()); }
568
569 constexpr containers extract() &&;
570 constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
571
572 constexpr iterator erase(iterator position);
573 constexpr iterator erase(const_iterator position);
574 constexpr size_type erase(const key_type& x);
575 template<class K> constexpr size_type erase(K&& x);
576 constexpr iterator erase(const_iterator first, const_iterator last);
577
578 constexpr void swap(flat_multimap&)
579 noexcept(is_nothrow_swappable_v<key_container_type> &&
580 is_nothrow_swappable_v<mapped_container_type> &&
581 is_nothrow_swappable_v<key_compare>);
582 constexpr void clear() noexcept;
583
584 // observers
585 constexpr key_compare key_comp() const;
586 constexpr value_compare value_comp() const;
587
588 constexpr const key_container_type& keys() const noexcept { return c.keys; }
589 constexpr const mapped_container_type& values() const noexcept { return c.values; }
590
591 // map operations
592 constexpr iterator find(const key_type& x);
593 constexpr const_iterator find(const key_type& x) const;
594 template<class K> constexpr iterator find(const K& x);
595 template<class K> constexpr const_iterator find(const K& x) const;
596
597 constexpr size_type count(const key_type& x) const;
598 template<class K> constexpr size_type count(const K& x) const;
599
600 constexpr bool contains(const key_type& x) const;
601 template<class K> constexpr bool contains(const K& x) const;
602
603 constexpr iterator lower_bound(const key_type& x);
604 constexpr const_iterator lower_bound(const key_type& x) const;
605 template<class K> constexpr iterator lower_bound(const K& x);
606 template<class K> constexpr const_iterator lower_bound(const K& x) const;
607
608 constexpr iterator upper_bound(const key_type& x);
609 constexpr const_iterator upper_bound(const key_type& x) const;
610 template<class K> constexpr iterator upper_bound(const K& x);
611 template<class K> constexpr const_iterator upper_bound(const K& x) const;
612
613 constexpr pair<iterator, iterator> equal_range(const key_type& x);
614 constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
615 template<class K>
616 constexpr pair<iterator, iterator> equal_range(const K& x);
617 template<class K>
618 constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const;
619
620 friend constexpr bool operator==(const flat_multimap& x, const flat_multimap& y);
621
622 friend constexpr synth-three-way-result<value_type>
623 operator<=>(const flat_multimap& x, const flat_multimap& y);
624
625 friend constexpr void swap(flat_multimap& x, flat_multimap& y)
626 noexcept(noexcept(x.swap(y)))
627 { x.swap(y); }
628
629 private:
630 containers c; // exposition only
631 key_compare compare; // exposition only
632 };
633
634 template<class KeyContainer, class MappedContainer,
635 class Compare = less<typename KeyContainer::value_type>>
636 flat_multimap(KeyContainer, MappedContainer, Compare = Compare())
637 -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
638 Compare, KeyContainer, MappedContainer>;
639
640 template<class KeyContainer, class MappedContainer, class Allocator>
641 flat_multimap(KeyContainer, MappedContainer, Allocator)
642 -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
643 less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>;
644 template<class KeyContainer, class MappedContainer, class Compare, class Allocator>
645 flat_multimap(KeyContainer, MappedContainer, Compare, Allocator)
646 -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
647 Compare, KeyContainer, MappedContainer>;
648
649 template<class KeyContainer, class MappedContainer,
650 class Compare = less<typename KeyContainer::value_type>>
651 flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare = Compare())
652 -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
653 Compare, KeyContainer, MappedContainer>;
654
655 template<class KeyContainer, class MappedContainer, class Allocator>
656 flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Allocator)
657 -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
658 less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>;
659 template<class KeyContainer, class MappedContainer, class Compare, class Allocator>
660 flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare, Allocator)
661 -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
662 Compare, KeyContainer, MappedContainer>;
663
664 template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>>
665 flat_multimap(InputIterator, InputIterator, Compare = Compare())
666 -> flat_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare>;
667
668 template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>>
669 flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())
670 -> flat_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare>;
671
672 template<ranges::input_range R, class Compare = less<range-key-type<R>>,
673 class Allocator = allocator<byte>>
674 flat_multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
675 -> flat_multimap<range-key-type<R>, range-mapped-type<R>, Compare,
676 vector<range-key-type<R>,
677 alloc-rebind<Allocator, range-key-type<R>>>,
678 vector<range-mapped-type<R>,
679 alloc-rebind<Allocator, range-mapped-type<R>>>>;
680
681 template<ranges::input_range R, class Allocator>
682 flat_multimap(from_range_t, R&&, Allocator)
683 -> flat_multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>,
684 vector<range-key-type<R>,
685 alloc-rebind<Allocator, range-key-type<R>>>,
686 vector<range-mapped-type<R>,
687 alloc-rebind<Allocator, range-mapped-type<R>>>>;
688
689 template<class Key, class T, class Compare = less<Key>>
690 flat_multimap(initializer_list<pair<Key, T>>, Compare = Compare())
691 -> flat_multimap<Key, T, Compare>;
692
693 template<class Key, class T, class Compare = less<Key>>
694 flat_multimap(sorted_equivalent_t, initializer_list<pair<Key, T>>, Compare = Compare())
695 -> flat_multimap<Key, T, Compare>;
46696
47697 template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
48 class Allocator>
698 class Allocator>
49699 struct uses_allocator<flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>,
50 Allocator>;
700 Allocator>
701 : bool_constant<uses_allocator_v<KeyContainer, Allocator> &&
702 uses_allocator_v<MappedContainer, Allocator>> { };
51703
52704 // [flat.multimap.erasure], erasure for flat_multimap
53705 template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
lib/libcxx/include/flat_set+543-8
......@@ -17,30 +17,565 @@
1717#include <initializer_list> // see [initializer.list.syn]
1818
1919namespace std {
20 struct sorted_unique_t { explicit sorted_unique_t() = default; };
21 inline constexpr sorted_unique_t sorted_unique{};
22
2023 // [flat.set], class template flat_set
2124 template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
22 class flat_set;
25 class flat_set {
26 public:
27 // types
28 using key_type = Key;
29 using value_type = Key;
30 using key_compare = Compare;
31 using value_compare = Compare;
32 using reference = value_type&;
33 using const_reference = const value_type&;
34 using size_type = KeyContainer::size_type;
35 using difference_type = KeyContainer::difference_type;
36 using iterator = implementation-defined; // see [container.requirements]
37 using const_iterator = implementation-defined; // see [container.requirements]
38 using reverse_iterator = std::reverse_iterator<iterator>;
39 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
40 using container_type = KeyContainer;
2341
24 struct sorted_unique_t { explicit sorted_unique_t() = default; };
25 inline constexpr sorted_unique_t sorted_unique{};
42 // [flat.set.cons], constructors
43 constexpr flat_set() : flat_set(key_compare()) { }
44
45 constexpr flat_set(const flat_set&);
46 constexpr flat_set(flat_set&&);
47 constexpr flat_set& operator=(const flat_set&);
48 constexpr flat_set& operator=(flat_set&&);
49
50 constexpr explicit flat_set(const key_compare& comp)
51 : c(), compare(comp) { }
52
53 constexpr explicit flat_set(container_type cont, const key_compare& comp = key_compare());
54
55 constexpr flat_set(sorted_unique_t, container_type cont,
56 const key_compare& comp = key_compare())
57 : c(std::move(cont)), compare(comp) { }
58
59 template<class InputIterator>
60 constexpr flat_set(InputIterator first, InputIterator last,
61 const key_compare& comp = key_compare())
62 : c(), compare(comp)
63 { insert(first, last); }
64
65 template<class InputIterator>
66 constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last,
67 const key_compare& comp = key_compare())
68 : c(first, last), compare(comp) { }
69
70 template<container-compatible-range<value_type> R>
71 constexpr flat_set(from_range_t, R&& rg)
72 : flat_set(from_range, std::forward<R>(rg), key_compare()) { }
73 template<container-compatible-range<value_type> R>
74 constexpr flat_set(from_range_t, R&& rg, const key_compare& comp)
75 : flat_set(comp)
76 { insert_range(std::forward<R>(rg)); }
77
78 constexpr flat_set(initializer_list<value_type> il, const key_compare& comp = key_compare())
79 : flat_set(il.begin(), il.end(), comp) { }
80
81 constexpr flat_set(sorted_unique_t, initializer_list<value_type> il,
82 const key_compare& comp = key_compare())
83 : flat_set(sorted_unique, il.begin(), il.end(), comp) { }
84
85 // [flat.set.cons.alloc], constructors with allocators
86
87 template<class Alloc>
88 constexpr explicit flat_set(const Alloc& a);
89 template<class Alloc>
90 constexpr flat_set(const key_compare& comp, const Alloc& a);
91 template<class Alloc>
92 constexpr flat_set(const container_type& cont, const Alloc& a);
93 template<class Alloc>
94 constexpr flat_set(const container_type& cont, const key_compare& comp, const Alloc& a);
95 template<class Alloc>
96 constexpr flat_set(sorted_unique_t, const container_type& cont, const Alloc& a);
97 template<class Alloc>
98 constexpr flat_set(sorted_unique_t, const container_type& cont,
99 const key_compare& comp, const Alloc& a);
100 template<class Alloc>
101 constexpr flat_set(const flat_set&, const Alloc& a);
102 template<class Alloc>
103 constexpr flat_set(flat_set&&, const Alloc& a);
104 template<class InputIterator, class Alloc>
105 constexpr flat_set(InputIterator first, InputIterator last, const Alloc& a);
106 template<class InputIterator, class Alloc>
107 constexpr flat_set(InputIterator first, InputIterator last,
108 const key_compare& comp, const Alloc& a);
109 template<class InputIterator, class Alloc>
110 constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last,
111 const Alloc& a);
112 template<class InputIterator, class Alloc>
113 constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last,
114 const key_compare& comp, const Alloc& a);
115 template<container-compatible-range<value_type> R, class Alloc>
116 constexpr flat_set(from_range_t, R&& rg, const Alloc& a);
117 template<container-compatible-range<value_type> R, class Alloc>
118 constexpr flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
119 template<class Alloc>
120 constexpr flat_set(initializer_list<value_type> il, const Alloc& a);
121 template<class Alloc>
122 constexpr flat_set(initializer_list<value_type> il, const key_compare& comp,
123 const Alloc& a);
124 template<class Alloc>
125 constexpr flat_set(sorted_unique_t, initializer_list<value_type> il, const Alloc& a);
126 template<class Alloc>
127 constexpr flat_set(sorted_unique_t, initializer_list<value_type> il,
128 const key_compare& comp, const Alloc& a);
129
130 constexpr flat_set& operator=(initializer_list<value_type>);
131
132 // iterators
133 constexpr iterator begin() noexcept;
134 constexpr const_iterator begin() const noexcept;
135 constexpr iterator end() noexcept;
136 constexpr const_iterator end() const noexcept;
137
138 constexpr reverse_iterator rbegin() noexcept;
139 constexpr const_reverse_iterator rbegin() const noexcept;
140 constexpr reverse_iterator rend() noexcept;
141 constexpr const_reverse_iterator rend() const noexcept;
142
143 constexpr const_iterator cbegin() const noexcept;
144 constexpr const_iterator cend() const noexcept;
145 constexpr const_reverse_iterator crbegin() const noexcept;
146 constexpr const_reverse_iterator crend() const noexcept;
147
148 // capacity
149 constexpr bool empty() const noexcept;
150 constexpr size_type size() const noexcept;
151 constexpr size_type max_size() const noexcept;
152
153 // [flat.set.modifiers], modifiers
154 template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args);
155 template<class... Args>
156 constexpr iterator emplace_hint(const_iterator position, Args&&... args);
157
158 constexpr pair<iterator, bool> insert(const value_type& x)
159 { return emplace(x); }
160 constexpr pair<iterator, bool> insert(value_type&& x)
161 { return emplace(std::move(x)); }
162 template<class K> constexpr pair<iterator, bool> insert(K&& x);
163 constexpr iterator insert(const_iterator position, const value_type& x)
164 { return emplace_hint(position, x); }
165 constexpr iterator insert(const_iterator position, value_type&& x)
166 { return emplace_hint(position, std::move(x)); }
167 template<class K> constexpr iterator insert(const_iterator hint, K&& x);
168
169 template<class InputIterator>
170 constexpr void insert(InputIterator first, InputIterator last);
171 template<class InputIterator>
172 constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last);
173 template<container-compatible-range<value_type> R>
174 constexpr void insert_range(R&& rg);
175 template<container-compatible-range<value_type> R>
176 constexpr void insert_range(sorted_unique_t, R&& rg);
177
178 constexpr void insert(initializer_list<value_type> il)
179 { insert(il.begin(), il.end()); }
180 constexpr void insert(sorted_unique_t, initializer_list<value_type> il)
181 { insert(sorted_unique, il.begin(), il.end()); }
182
183 constexpr container_type extract() &&;
184 constexpr void replace(container_type&&);
185
186 constexpr iterator erase(iterator position) requires (!same_as<iterator, const_iterator>);
187 constexpr iterator erase(const_iterator position);
188 constexpr size_type erase(const key_type& x);
189 template<class K> constexpr size_type erase(K&& x);
190 constexpr iterator erase(const_iterator first, const_iterator last);
191
192 constexpr void swap(flat_set& y) noexcept(see below);
193 constexpr void clear() noexcept;
194
195 // observers
196 constexpr key_compare key_comp() const;
197 constexpr value_compare value_comp() const;
198
199 // set operations
200 constexpr iterator find(const key_type& x);
201 constexpr const_iterator find(const key_type& x) const;
202 template<class K> constexpr iterator find(const K& x);
203 template<class K> constexpr const_iterator find(const K& x) const;
204
205 constexpr size_type count(const key_type& x) const;
206 template<class K> constexpr size_type count(const K& x) const;
207
208 constexpr bool contains(const key_type& x) const;
209 template<class K> constexpr bool contains(const K& x) const;
210
211 constexpr iterator lower_bound(const key_type& x);
212 constexpr const_iterator lower_bound(const key_type& x) const;
213 template<class K> constexpr iterator lower_bound(const K& x);
214 template<class K> constexpr const_iterator lower_bound(const K& x) const;
215
216 constexpr iterator upper_bound(const key_type& x);
217 constexpr const_iterator upper_bound(const key_type& x) const;
218 template<class K> constexpr iterator upper_bound(const K& x);
219 template<class K> constexpr const_iterator upper_bound(const K& x) const;
220
221 constexpr pair<iterator, iterator> equal_range(const key_type& x);
222 constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
223 template<class K>
224 constexpr pair<iterator, iterator> equal_range(const K& x);
225 template<class K>
226 constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const;
227
228 friend constexpr bool operator==(const flat_set& x, const flat_set& y);
229
230 friend constexpr synth-three-way-result<value_type>
231 operator<=>(const flat_set& x, const flat_set& y);
232
233 friend constexpr void swap(flat_set& x, flat_set& y) noexcept(noexcept(x.swap(y)))
234 { x.swap(y); }
235
236 private:
237 container_type c; // exposition only
238 key_compare compare; // exposition only
239 };
240
241 template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
242 flat_set(KeyContainer, Compare = Compare())
243 -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
244 template<class KeyContainer, class Allocator>
245 flat_set(KeyContainer, Allocator)
246 -> flat_set<typename KeyContainer::value_type,
247 less<typename KeyContainer::value_type>, KeyContainer>;
248 template<class KeyContainer, class Compare, class Allocator>
249 flat_set(KeyContainer, Compare, Allocator)
250 -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
251
252 template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
253 flat_set(sorted_unique_t, KeyContainer, Compare = Compare())
254 -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
255 template<class KeyContainer, class Allocator>
256 flat_set(sorted_unique_t, KeyContainer, Allocator)
257 -> flat_set<typename KeyContainer::value_type,
258 less<typename KeyContainer::value_type>, KeyContainer>;
259 template<class KeyContainer, class Compare, class Allocator>
260 flat_set(sorted_unique_t, KeyContainer, Compare, Allocator)
261 -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
262
263 template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
264 flat_set(InputIterator, InputIterator, Compare = Compare())
265 -> flat_set<iter-value-type<InputIterator>, Compare>;
266
267 template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
268 flat_set(sorted_unique_t, InputIterator, InputIterator, Compare = Compare())
269 -> flat_set<iter-value-type<InputIterator>, Compare>;
270
271 template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
272 class Allocator = allocator<ranges::range_value_t<R>>>
273 flat_set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
274 -> flat_set<ranges::range_value_t<R>, Compare,
275 vector<ranges::range_value_t<R>,
276 alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
277
278 template<ranges::input_range R, class Allocator>
279 flat_set(from_range_t, R&&, Allocator)
280 -> flat_set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,
281 vector<ranges::range_value_t<R>,
282 alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
283
284 template<class Key, class Compare = less<Key>>
285 flat_set(initializer_list<Key>, Compare = Compare())
286 -> flat_set<Key, Compare>;
287
288 template<class Key, class Compare = less<Key>>
289 flat_set(sorted_unique_t, initializer_list<Key>, Compare = Compare())
290 -> flat_set<Key, Compare>;
26291
27292 template<class Key, class Compare, class KeyContainer, class Allocator>
28 struct uses_allocator<flat_set<Key, Compare, KeyContainer>, Allocator>;
293 struct uses_allocator<flat_set<Key, Compare, KeyContainer>, Allocator>
294 : bool_constant<uses_allocator_v<KeyContainer, Allocator>> { };
29295
30296 // [flat.set.erasure], erasure for flat_set
31297 template<class Key, class Compare, class KeyContainer, class Predicate>
32298 typename flat_set<Key, Compare, KeyContainer>::size_type
33299 erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred);
34300
301 struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
302 inline constexpr sorted_equivalent_t sorted_equivalent{};
303
35304 // [flat.multiset], class template flat_multiset
36305 template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
37 class flat_multiset;
306 class flat_multiset {
307 public:
308 // types
309 using key_type = Key;
310 using value_type = Key;
311 using key_compare = Compare;
312 using value_compare = Compare;
313 using reference = value_type&;
314 using const_reference = const value_type&;
315 using size_type = KeyContainer::size_type;
316 using difference_type = KeyContainer::difference_type;
317 using iterator = implementation-defined; // see [container.requirements]
318 using const_iterator = implementation-defined; // see [container.requirements]
319 using reverse_iterator = std::reverse_iterator<iterator>;
320 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
321 using container_type = KeyContainer;
38322
39 struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
40 inline constexpr sorted_equivalent_t sorted_equivalent{};
323 // [flat.multiset.cons], constructors
324 constexpr flat_multiset() : flat_multiset(key_compare()) { }
325
326 constexpr flat_multiset(const flat_multiset&);
327 constexpr flat_multiset(flat_multiset&&);
328 constexpr flat_multiset& operator=(const flat_multiset&);
329 constexpr flat_multiset& operator=(flat_multiset&&);
330
331 constexpr explicit flat_multiset(const key_compare& comp)
332 : c(), compare(comp) { }
333
334 constexpr explicit flat_multiset(container_type cont,
335 const key_compare& comp = key_compare());
336
337 constexpr flat_multiset(sorted_equivalent_t, container_type cont,
338 const key_compare& comp = key_compare())
339 : c(std::move(cont)), compare(comp) { }
340
341 template<class InputIterator>
342 constexpr flat_multiset(InputIterator first, InputIterator last,
343 const key_compare& comp = key_compare())
344 : c(), compare(comp)
345 { insert(first, last); }
346
347 template<class InputIterator>
348 constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
349 const key_compare& comp = key_compare())
350 : c(first, last), compare(comp) { }
351
352 template<container-compatible-range<value_type> R>
353 constexpr flat_multiset(from_range_t, R&& rg)
354 : flat_multiset(from_range, std::forward<R>(rg), key_compare()) { }
355 template<container-compatible-range<value_type> R>
356 constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp)
357 : flat_multiset(comp)
358 { insert_range(std::forward<R>(rg)); }
359
360 constexpr flat_multiset(initializer_list<value_type> il,
361 const key_compare& comp = key_compare())
362 : flat_multiset(il.begin(), il.end(), comp) { }
363
364 constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
365 const key_compare& comp = key_compare())
366 : flat_multiset(sorted_equivalent, il.begin(), il.end(), comp) { }
367
368 // [flat.multiset.cons.alloc], constructors with allocators
369
370 template<class Alloc>
371 constexpr explicit flat_multiset(const Alloc& a);
372 template<class Alloc>
373 constexpr flat_multiset(const key_compare& comp, const Alloc& a);
374 template<class Alloc>
375 constexpr flat_multiset(const container_type& cont, const Alloc& a);
376 template<class Alloc>
377 constexpr flat_multiset(const container_type& cont, const key_compare& comp,
378 const Alloc& a);
379 template<class Alloc>
380 constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a);
381 template<class Alloc>
382 constexpr flat_multiset(sorted_equivalent_t, const container_type& cont,
383 const key_compare& comp, const Alloc& a);
384 template<class Alloc>
385 constexpr flat_multiset(const flat_multiset&, const Alloc& a);
386 template<class Alloc>
387 constexpr flat_multiset(flat_multiset&&, const Alloc& a);
388 template<class InputIterator, class Alloc>
389 constexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a);
390 template<class InputIterator, class Alloc>
391 constexpr flat_multiset(InputIterator first, InputIterator last,
392 const key_compare& comp, const Alloc& a);
393 template<class InputIterator, class Alloc>
394 constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
395 const Alloc& a);
396 template<class InputIterator, class Alloc>
397 constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
398 const key_compare& comp, const Alloc& a);
399 template<container-compatible-range<value_type> R, class Alloc>
400 constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a);
401 template<container-compatible-range<value_type> R, class Alloc>
402 constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
403 template<class Alloc>
404 constexpr flat_multiset(initializer_list<value_type> il, const Alloc& a);
405 template<class Alloc>
406 constexpr flat_multiset(initializer_list<value_type> il, const key_compare& comp,
407 const Alloc& a);
408 template<class Alloc>
409 constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
410 const Alloc& a);
411 template<class Alloc>
412 constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
413 const key_compare& comp, const Alloc& a);
414
415 constexpr flat_multiset& operator=(initializer_list<value_type>);
416
417 // iterators
418 constexpr iterator begin() noexcept;
419 constexpr const_iterator begin() const noexcept;
420 constexpr iterator end() noexcept;
421 constexpr const_iterator end() const noexcept;
422
423 constexpr reverse_iterator rbegin() noexcept;
424 constexpr const_reverse_iterator rbegin() const noexcept;
425 constexpr reverse_iterator rend() noexcept;
426 constexpr const_reverse_iterator rend() const noexcept;
427
428 constexpr const_iterator cbegin() const noexcept;
429 constexpr const_iterator cend() const noexcept;
430 constexpr const_reverse_iterator crbegin() const noexcept;
431 constexpr const_reverse_iterator crend() const noexcept;
432
433 // capacity
434 constexpr bool empty() const noexcept;
435 constexpr size_type size() const noexcept;
436 constexpr size_type max_size() const noexcept;
437
438 // [flat.multiset.modifiers], modifiers
439 template<class... Args> constexpr iterator emplace(Args&&... args);
440 template<class... Args>
441 constexpr iterator emplace_hint(const_iterator position, Args&&... args);
442
443 constexpr iterator insert(const value_type& x)
444 { return emplace(x); }
445 constexpr iterator insert(value_type&& x)
446 { return emplace(std::move(x)); }
447 constexpr iterator insert(const_iterator position, const value_type& x)
448 { return emplace_hint(position, x); }
449 constexpr iterator insert(const_iterator position, value_type&& x)
450 { return emplace_hint(position, std::move(x)); }
451
452 template<class InputIterator>
453 constexpr void insert(InputIterator first, InputIterator last);
454 template<class InputIterator>
455 constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
456 template<container-compatible-range<value_type> R>
457 constexpr void insert_range(R&& rg);
458 template<container-compatible-range<value_type> R>
459 constexpr void insert_range(sorted_equivalent_t, R&& rg);
460
461 constexpr void insert(initializer_list<value_type> il)
462 { insert(il.begin(), il.end()); }
463 constexpr void insert(sorted_equivalent_t, initializer_list<value_type> il)
464 { insert(sorted_equivalent, il.begin(), il.end()); }
465
466 constexpr container_type extract() &&;
467 constexpr void replace(container_type&&);
468
469 constexpr iterator erase(iterator position) requires (!same_as<iterator, const_iterator>);
470 constexpr iterator erase(const_iterator position);
471 constexpr size_type erase(const key_type& x);
472 template<class K> constexpr size_type erase(K&& x);
473 constexpr iterator erase(const_iterator first, const_iterator last);
474
475 constexpr void swap(flat_multiset& y) noexcept(see below);
476 constexpr void clear() noexcept;
477
478 // observers
479 constexpr key_compare key_comp() const;
480 constexpr value_compare value_comp() const;
481
482 // set operations
483 constexpr iterator find(const key_type& x);
484 constexpr const_iterator find(const key_type& x) const;
485 template<class K> constexpr iterator find(const K& x);
486 template<class K> constexpr const_iterator find(const K& x) const;
487
488 constexpr size_type count(const key_type& x) const;
489 template<class K> constexpr size_type count(const K& x) const;
490
491 constexpr bool contains(const key_type& x) const;
492 template<class K> constexpr bool contains(const K& x) const;
493
494 constexpr iterator lower_bound(const key_type& x);
495 constexpr const_iterator lower_bound(const key_type& x) const;
496 template<class K> constexpr iterator lower_bound(const K& x);
497 template<class K> constexpr const_iterator lower_bound(const K& x) const;
498
499 constexpr iterator upper_bound(const key_type& x);
500 constexpr const_iterator upper_bound(const key_type& x) const;
501 template<class K> constexpr iterator upper_bound(const K& x);
502 template<class K> constexpr const_iterator upper_bound(const K& x) const;
503
504 constexpr pair<iterator, iterator> equal_range(const key_type& x);
505 constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
506 template<class K>
507 constexpr pair<iterator, iterator> equal_range(const K& x);
508 template<class K>
509 constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const;
510
511 friend constexpr bool operator==(const flat_multiset& x, const flat_multiset& y);
512
513 friend constexpr synth-three-way-result<value_type>
514 operator<=>(const flat_multiset& x, const flat_multiset& y);
515
516 friend constexpr void swap(flat_multiset& x, flat_multiset& y)
517 noexcept(noexcept(x.swap(y)))
518 { x.swap(y); }
519
520 private:
521 container_type c; // exposition only
522 key_compare compare; // exposition only
523 };
524
525 template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
526 flat_multiset(KeyContainer, Compare = Compare())
527 -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
528 template<class KeyContainer, class Allocator>
529 flat_multiset(KeyContainer, Allocator)
530 -> flat_multiset<typename KeyContainer::value_type,
531 less<typename KeyContainer::value_type>, KeyContainer>;
532 template<class KeyContainer, class Compare, class Allocator>
533 flat_multiset(KeyContainer, Compare, Allocator)
534 -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
535
536 template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
537 flat_multiset(sorted_equivalent_t, KeyContainer, Compare = Compare())
538 -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
539 template<class KeyContainer, class Allocator>
540 flat_multiset(sorted_equivalent_t, KeyContainer, Allocator)
541 -> flat_multiset<typename KeyContainer::value_type,
542 less<typename KeyContainer::value_type>, KeyContainer>;
543 template<class KeyContainer, class Compare, class Allocator>
544 flat_multiset(sorted_equivalent_t, KeyContainer, Compare, Allocator)
545 -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
546
547 template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
548 flat_multiset(InputIterator, InputIterator, Compare = Compare())
549 -> flat_multiset<iter-value-type<InputIterator>, Compare>;
550
551 template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
552 flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())
553 -> flat_multiset<iter-value-type<InputIterator>, Compare>;
554
555 template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
556 class Allocator = allocator<ranges::range_value_t<R>>>
557 flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
558 -> flat_multiset<ranges::range_value_t<R>, Compare,
559 vector<ranges::range_value_t<R>,
560 alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
561
562 template<ranges::input_range R, class Allocator>
563 flat_multiset(from_range_t, R&&, Allocator)
564 -> flat_multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,
565 vector<ranges::range_value_t<R>,
566 alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
567
568 template<class Key, class Compare = less<Key>>
569 flat_multiset(initializer_list<Key>, Compare = Compare())
570 -> flat_multiset<Key, Compare>;
571
572 template<class Key, class Compare = less<Key>>
573 flat_multiset(sorted_equivalent_t, initializer_list<Key>, Compare = Compare())
574 -> flat_multiset<Key, Compare>;
41575
42576 template<class Key, class Compare, class KeyContainer, class Allocator>
43 struct uses_allocator<flat_multiset<Key, Compare, KeyContainer>, Allocator>;
577 struct uses_allocator<flat_multiset<Key, Compare, KeyContainer>, Allocator>
578 : bool_constant<uses_allocator_v<KeyContainer, Allocator>> { };
44579
45580 // [flat.multiset.erasure], erasure for flat_multiset
46581 template<class Key, class Compare, class KeyContainer, class Predicate>
lib/libcxx/include/float.h+16-16
......@@ -71,29 +71,29 @@ Macros:
7171*/
7272
7373#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
74# include <__cxx03/float.h>
74# include <__cxx03/__config>
7575#else
7676# include <__config>
77#endif
7778
78# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
79# pragma GCC system_header
80# endif
79#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
80# pragma GCC system_header
81#endif
8182
82# if __has_include_next(<float.h>)
83# include_next <float.h>
84# endif
83#if __has_include_next(<float.h>)
84# include_next <float.h>
85#endif
8586
86# ifdef __cplusplus
87#ifdef __cplusplus
8788
88# ifndef FLT_EVAL_METHOD
89# define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
90# endif
89# ifndef FLT_EVAL_METHOD
90# define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
91# endif
9192
92# ifndef DECIMAL_DIG
93# define DECIMAL_DIG __DECIMAL_DIG__
94# endif
93# ifndef DECIMAL_DIG
94# define DECIMAL_DIG __DECIMAL_DIG__
95# endif
9596
96# endif // __cplusplus
97#endif // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
97#endif // __cplusplus
9898
9999#endif // _LIBCPP_FLOAT_H
lib/libcxx/include/forward_list+33-53
......@@ -223,18 +223,17 @@ template <class T, class Allocator, class Predicate>
223223# include <__ranges/concepts.h>
224224# include <__ranges/container_compatible_range.h>
225225# include <__ranges/from_range.h>
226# include <__type_traits/conditional.h>
227226# include <__type_traits/container_traits.h>
228227# include <__type_traits/enable_if.h>
229228# include <__type_traits/is_allocator.h>
230229# include <__type_traits/is_const.h>
231230# include <__type_traits/is_nothrow_assignable.h>
232231# include <__type_traits/is_nothrow_constructible.h>
233# include <__type_traits/is_pointer.h>
234232# include <__type_traits/is_same.h>
235233# include <__type_traits/is_swappable.h>
236234# include <__type_traits/remove_cv.h>
237235# include <__type_traits/type_identity.h>
236# include <__utility/exception_guard.h>
238237# include <__utility/forward.h>
239238# include <__utility/move.h>
240239# include <__utility/swap.h>
......@@ -283,17 +282,6 @@ struct __forward_node_traits {
283282 typedef _NodePtr __node_pointer;
284283 typedef __forward_begin_node<_NodePtr> __begin_node;
285284 typedef __rebind_pointer_t<_NodePtr, __begin_node> __begin_node_pointer;
286
287// TODO(LLVM 22): Remove this check
288# ifndef _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB
289 static_assert(sizeof(__begin_node_pointer) == sizeof(__node_pointer) && _LIBCPP_ALIGNOF(__begin_node_pointer) ==
290 _LIBCPP_ALIGNOF(__node_pointer),
291 "It looks like you are using std::forward_list with a fancy pointer type that thas a different "
292 "representation depending on whether it points to a forward_list base pointer or a forward_list node "
293 "pointer (both of which are implementation details of the standard library). This means that your ABI "
294 "is being broken between LLVM 19 and LLVM 20. If you don't care about your ABI being broken, define "
295 "the _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB macro to silence this diagnostic.");
296# endif
297285};
298286
299287template <class _NodePtr>
......@@ -680,7 +668,7 @@ public:
680668# endif
681669 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v);
682670
683 template <__enable_if_t<__is_allocator<_Alloc>::value, int> = 0>
671 template <__enable_if_t<__is_allocator_v<_Alloc>, int> = 0>
684672 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI
685673 forward_list(size_type __n, const value_type& __v, const allocator_type& __a)
686674 : __base(__a) {
......@@ -744,50 +732,52 @@ public:
744732
745733 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);
746734
747 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
735 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
748736 return allocator_type(this->__alloc_);
749737 }
750738
751 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
739 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
752740 return iterator(__base::__before_begin()->__next_);
753741 }
754 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
742 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
755743 return const_iterator(__base::__before_begin()->__next_);
756744 }
757 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(nullptr); }
758 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
745 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
746 return iterator(nullptr);
747 }
748 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
759749 return const_iterator(nullptr);
760750 }
761751
762 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
752 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
763753 return const_iterator(__base::__before_begin()->__next_);
764754 }
765 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
755 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
766756 return const_iterator(nullptr);
767757 }
768758
769 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator before_begin() _NOEXCEPT {
759 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator before_begin() _NOEXCEPT {
770760 return iterator(__base::__before_begin());
771761 }
772 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator before_begin() const _NOEXCEPT {
762 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator before_begin() const _NOEXCEPT {
773763 return const_iterator(__base::__before_begin());
774764 }
775 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbefore_begin() const _NOEXCEPT {
765 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbefore_begin() const _NOEXCEPT {
776766 return const_iterator(__base::__before_begin());
777767 }
778768
779769 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
780770 return __base::__before_begin()->__next_ == nullptr;
781771 }
782 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
772 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
783773 return std::min<size_type>(__node_traits::max_size(this->__alloc_), numeric_limits<difference_type>::max());
784774 }
785775
786 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() {
776 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() {
787777 _LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list");
788778 return __base::__before_begin()->__next_->__get_value();
789779 }
790 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const {
780 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const {
791781 _LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list");
792782 return __base::__before_begin()->__next_->__get_value();
793783 }
......@@ -918,22 +908,22 @@ private:
918908
919909# if _LIBCPP_STD_VER >= 17
920910template <class _InputIterator,
921 class _Alloc = allocator<__iter_value_type<_InputIterator>>,
911 class _Alloc = allocator<__iterator_value_type<_InputIterator>>,
922912 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
923 class = enable_if_t<__is_allocator<_Alloc>::value> >
924forward_list(_InputIterator, _InputIterator) -> forward_list<__iter_value_type<_InputIterator>, _Alloc>;
913 class = enable_if_t<__is_allocator_v<_Alloc>>>
914forward_list(_InputIterator, _InputIterator) -> forward_list<__iterator_value_type<_InputIterator>, _Alloc>;
925915
926916template <class _InputIterator,
927917 class _Alloc,
928918 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
929 class = enable_if_t<__is_allocator<_Alloc>::value> >
930forward_list(_InputIterator, _InputIterator, _Alloc) -> forward_list<__iter_value_type<_InputIterator>, _Alloc>;
919 class = enable_if_t<__is_allocator_v<_Alloc>>>
920forward_list(_InputIterator, _InputIterator, _Alloc) -> forward_list<__iterator_value_type<_InputIterator>, _Alloc>;
931921# endif
932922
933923# if _LIBCPP_STD_VER >= 23
934924template <ranges::input_range _Range,
935925 class _Alloc = allocator<ranges::range_value_t<_Range>>,
936 class = enable_if_t<__is_allocator<_Alloc>::value> >
926 class = enable_if_t<__is_allocator_v<_Alloc>>>
937927forward_list(from_range_t, _Range&&, _Alloc = _Alloc()) -> forward_list<ranges::range_value_t<_Range>, _Alloc>;
938928# endif
939929
......@@ -1180,22 +1170,17 @@ forward_list<_Tp, _Alloc>::__insert_after(const_iterator __p, size_type __n, _Ar
11801170 if (__n > 0) {
11811171 __node_pointer __first = this->__create_node(/* next = */ nullptr, std::forward<_Args>(__args)...);
11821172 __node_pointer __last = __first;
1183# if _LIBCPP_HAS_EXCEPTIONS
1184 try {
1185# endif // _LIBCPP_HAS_EXCEPTIONS
1186 for (--__n; __n != 0; --__n, __last = __last->__next_) {
1187 __last->__next_ = this->__create_node(/* next = */ nullptr, std::forward<_Args>(__args)...);
1188 }
1189# if _LIBCPP_HAS_EXCEPTIONS
1190 } catch (...) {
1173 auto __guard = std::__make_exception_guard([&] {
11911174 while (__first != nullptr) {
11921175 __node_pointer __next = __first->__next_;
11931176 this->__delete_node(__first);
11941177 __first = __next;
11951178 }
1196 throw;
1179 });
1180 for (--__n; __n != 0; --__n, __last = __last->__next_) {
1181 __last->__next_ = this->__create_node(/* next = */ nullptr, std::forward<_Args>(__args)...);
11971182 }
1198# endif // _LIBCPP_HAS_EXCEPTIONS
1183 __guard.__complete();
11991184 __last->__next_ = __r->__next_;
12001185 __r->__next_ = __first;
12011186 __r = std::__static_fancy_pointer_cast<__begin_node_pointer>(__last);
......@@ -1220,22 +1205,17 @@ forward_list<_Tp, _Alloc>::__insert_after_with_sentinel(const_iterator __p, _Inp
12201205 __node_pointer __first = this->__create_node(/* next = */ nullptr, *__f);
12211206 __node_pointer __last = __first;
12221207
1223# if _LIBCPP_HAS_EXCEPTIONS
1224 try {
1225# endif // _LIBCPP_HAS_EXCEPTIONS
1226 for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_))) {
1227 __last->__next_ = this->__create_node(/* next = */ nullptr, *__f);
1228 }
1229# if _LIBCPP_HAS_EXCEPTIONS
1230 } catch (...) {
1208 auto __guard = std::__make_exception_guard([&] {
12311209 while (__first != nullptr) {
12321210 __node_pointer __next = __first->__next_;
12331211 this->__delete_node(__first);
12341212 __first = __next;
12351213 }
1236 throw;
1214 });
1215 for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_))) {
1216 __last->__next_ = this->__create_node(/* next = */ nullptr, *__f);
12371217 }
1238# endif // _LIBCPP_HAS_EXCEPTIONS
1218 __guard.__complete();
12391219
12401220 __last->__next_ = __r->__next_;
12411221 __r->__next_ = __first;
lib/libcxx/include/fstream+57-42
......@@ -221,7 +221,7 @@ _LIBCPP_PUSH_MACROS
221221
222222_LIBCPP_BEGIN_NAMESPACE_STD
223223
224# if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_WIN32API)
224# if _LIBCPP_STD_VER >= 23 && defined(_LIBCPP_WIN32API)
225225_LIBCPP_EXPORTED_FROM_ABI void* __filebuf_windows_native_handle(FILE* __file) noexcept;
226226# endif
227227
......@@ -254,7 +254,7 @@ public:
254254 void swap(basic_filebuf& __rhs);
255255
256256 // 27.9.1.4 Members:
257 _LIBCPP_HIDE_FROM_ABI bool is_open() const;
257 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool is_open() const;
258258 basic_filebuf* open(const char* __s, ios_base::openmode __mode);
259259# if _LIBCPP_HAS_OPEN_WITH_WCHAR
260260 basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode);
......@@ -262,15 +262,14 @@ public:
262262 _LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const string& __s, ios_base::openmode __mode);
263263
264264# if _LIBCPP_STD_VER >= 17
265 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI basic_filebuf*
266 open(const filesystem::path& __p, ios_base::openmode __mode) {
265 _LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const filesystem::path& __p, ios_base::openmode __mode) {
267266 return open(__p.c_str(), __mode);
268267 }
269268# endif
270269 _LIBCPP_HIDE_FROM_ABI basic_filebuf* __open(int __fd, ios_base::openmode __mode);
271270 basic_filebuf* close();
272271# if _LIBCPP_STD_VER >= 26
273 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
272 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
274273 _LIBCPP_ASSERT_UNCATEGORIZED(this->is_open(), "File must be opened");
275274# if defined(_LIBCPP_WIN32API)
276275 return std::__filebuf_windows_native_handle(__file_);
......@@ -299,6 +298,16 @@ protected:
299298 int sync() override;
300299 void imbue(const locale& __loc) override;
301300
301 _LIBCPP_HIDE_FROM_ABI_VIRTUAL streamsize xsputn(const char_type* __str, streamsize __len) override {
302 if (__always_noconv_ && __len >= (this->epptr() - this->pbase())) {
303 if (traits_type::eq_int_type(overflow(), traits_type::eof()))
304 return 0;
305
306 return std::fwrite(__str, sizeof(char_type), __len, __file_);
307 }
308 return basic_streambuf<_CharT, _Traits>::xsputn(__str, __len);
309 }
310
302311private:
303312 char* __extbuf_;
304313 const char* __extbufnext_;
......@@ -401,6 +410,14 @@ private:
401410 }
402411 }
403412 }
413
414 _LIBCPP_HIDE_FROM_ABI typename traits_type::int_type __overflow_failed() {
415 if (this->pptr() == this->epptr() + 1) {
416 this->pbump(-1); // lose the character we overflowed above -- we don't really have a
417 // choice since we couldn't commit the contents of the put area
418 }
419 return traits_type::eof();
420 }
404421};
405422
406423template <class _CharT, class _Traits>
......@@ -742,7 +759,12 @@ basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::close() {
742759 if (fclose(__h.release()))
743760 __rt = nullptr;
744761 __file_ = nullptr;
745 setbuf(0, 0);
762 // Reset the get and the put areas without getting rid of the underlying buffers,
763 // which might have been configured by the user. Make sure to keep the buffers
764 // since the user may re-open the stream.
765 this->setg(nullptr, nullptr, nullptr);
766 this->setp(nullptr, nullptr);
767 __cm_ = __no_io_operations;
746768 }
747769 return __rt;
748770}
......@@ -821,14 +843,6 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
821843
822844template <class _CharT, class _Traits>
823845typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {
824 auto __failed = [this]() {
825 if (this->pptr() == this->epptr() + 1) {
826 this->pbump(-1); // lose the character we overflowed above -- we don't really have a
827 // choice since we couldn't commit the contents of the put area
828 }
829 return traits_type::eof();
830 };
831
832846 if (__file_ == nullptr)
833847 return traits_type::eof();
834848 __write_mode();
......@@ -850,7 +864,7 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
850864 if (__always_noconv_) {
851865 size_t __n = static_cast<size_t>(this->pptr() - this->pbase());
852866 if (std::fwrite(this->pbase(), sizeof(char_type), __n, __file_) != __n) {
853 return __failed();
867 return __overflow_failed();
854868 }
855869 } else {
856870 if (!__cv_)
......@@ -864,14 +878,14 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
864878 do {
865879 codecvt_base::result __r = __cv_->out(__st_, __b, __p, __end, __extbuf_, __extbuf_ + __ebs_, __extbuf_end);
866880 if (__end == __b) {
867 return __failed();
881 return __overflow_failed();
868882 }
869883
870884 // No conversion needed: output characters directly to the file, done.
871885 if (__r == codecvt_base::noconv) {
872886 size_t __n = static_cast<size_t>(__p - __b);
873887 if (std::fwrite(__b, 1, __n, __file_) != __n) {
874 return __failed();
888 return __overflow_failed();
875889 }
876890 break;
877891
......@@ -879,7 +893,7 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
879893 } else if (__r == codecvt_base::ok) {
880894 size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);
881895 if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) {
882 return __failed();
896 return __overflow_failed();
883897 }
884898 break;
885899
......@@ -888,13 +902,13 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
888902 } else if (__r == codecvt_base::partial) {
889903 size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);
890904 if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) {
891 return __failed();
905 return __overflow_failed();
892906 }
893907 __b = const_cast<char_type*>(__end);
894908 continue;
895909
896910 } else {
897 return __failed();
911 return __overflow_failed();
898912 }
899913 } while (true);
900914 }
......@@ -977,7 +991,7 @@ template <class _CharT, class _Traits>
977991int basic_filebuf<_CharT, _Traits>::__fseek(FILE* __file, pos_type __offset, int __whence) {
978992# if defined(_LIBCPP_MSVCRT_LIKE)
979993 return _fseeki64(__file, __offset, __whence);
980# elif defined(_NEWLIB_VERSION)
994# elif _LIBCPP_LIBC_NEWLIB
981995 return fseek(__file, __offset, __whence);
982996# else
983997 return ::fseeko(__file, __offset, __whence);
......@@ -988,7 +1002,7 @@ template <class _CharT, class _Traits>
9881002typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>::__ftell(FILE* __file) {
9891003# if defined(_LIBCPP_MSVCRT_LIKE)
9901004 return _ftelli64(__file);
991# elif defined(_NEWLIB_VERSION)
1005# elif _LIBCPP_LIBC_NEWLIB
9921006 return ftell(__file);
9931007# else
9941008 return ftello(__file);
......@@ -1147,27 +1161,27 @@ public:
11471161 _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
11481162# if _LIBCPP_STD_VER >= 17
11491163 template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
1150 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
1151 _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const _Tp& __p, ios_base::openmode __mode = ios_base::in)
1164 _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const _Tp& __p, ios_base::openmode __mode = ios_base::in)
11521165 : basic_ifstream(__p.c_str(), __mode) {}
11531166# endif // _LIBCPP_STD_VER >= 17
11541167 _LIBCPP_HIDE_FROM_ABI basic_ifstream(basic_ifstream&& __rhs);
11551168 _LIBCPP_HIDE_FROM_ABI basic_ifstream& operator=(basic_ifstream&& __rhs);
11561169 _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs);
11571170
1158 _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
1171 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
11591172# if _LIBCPP_STD_VER >= 26
1160 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
1173 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
1174 return rdbuf()->native_handle();
1175 }
11611176# endif
1162 _LIBCPP_HIDE_FROM_ABI bool is_open() const;
1177 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool is_open() const;
11631178 void open(const char* __s, ios_base::openmode __mode = ios_base::in);
11641179# if _LIBCPP_HAS_OPEN_WITH_WCHAR
11651180 void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
11661181# endif
11671182 void open(const string& __s, ios_base::openmode __mode = ios_base::in);
11681183# if _LIBCPP_STD_VER >= 17
1169 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1170 open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) {
1184 _LIBCPP_HIDE_FROM_ABI void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) {
11711185 return open(__p.c_str(), __mode);
11721186 }
11731187# endif // _LIBCPP_STD_VER >= 17
......@@ -1304,8 +1318,7 @@ public:
13041318
13051319# if _LIBCPP_STD_VER >= 17
13061320 template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
1307 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
1308 _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const _Tp& __p, ios_base::openmode __mode = ios_base::out)
1321 _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const _Tp& __p, ios_base::openmode __mode = ios_base::out)
13091322 : basic_ofstream(__p.c_str(), __mode) {}
13101323# endif // _LIBCPP_STD_VER >= 17
13111324
......@@ -1313,11 +1326,13 @@ public:
13131326 _LIBCPP_HIDE_FROM_ABI basic_ofstream& operator=(basic_ofstream&& __rhs);
13141327 _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream& __rhs);
13151328
1316 _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
1329 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
13171330# if _LIBCPP_STD_VER >= 26
1318 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
1331 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
1332 return rdbuf()->native_handle();
1333 }
13191334# endif
1320 _LIBCPP_HIDE_FROM_ABI bool is_open() const;
1335 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool is_open() const;
13211336 void open(const char* __s, ios_base::openmode __mode = ios_base::out);
13221337# if _LIBCPP_HAS_OPEN_WITH_WCHAR
13231338 void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
......@@ -1325,8 +1340,7 @@ public:
13251340 void open(const string& __s, ios_base::openmode __mode = ios_base::out);
13261341
13271342# if _LIBCPP_STD_VER >= 17
1328 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1329 open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) {
1343 _LIBCPP_HIDE_FROM_ABI void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) {
13301344 return open(__p.c_str(), __mode);
13311345 }
13321346# endif // _LIBCPP_STD_VER >= 17
......@@ -1466,8 +1480,7 @@ public:
14661480
14671481# if _LIBCPP_STD_VER >= 17
14681482 template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
1469 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(
1470 const _Tp& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
1483 _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const _Tp& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
14711484 : basic_fstream(__p.c_str(), __mode) {}
14721485# endif // _LIBCPP_STD_VER >= 17
14731486
......@@ -1477,11 +1490,13 @@ public:
14771490
14781491 _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream& __rhs);
14791492
1480 _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
1493 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
14811494# if _LIBCPP_STD_VER >= 26
1482 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
1495 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
1496 return rdbuf()->native_handle();
1497 }
14831498# endif
1484 _LIBCPP_HIDE_FROM_ABI bool is_open() const;
1499 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool is_open() const;
14851500 _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
14861501# if _LIBCPP_HAS_OPEN_WITH_WCHAR
14871502 void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
......@@ -1489,7 +1504,7 @@ public:
14891504 _LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
14901505
14911506# if _LIBCPP_STD_VER >= 17
1492 _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1507 _LIBCPP_HIDE_FROM_ABI void
14931508 open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) {
14941509 return open(__p.c_str(), __mode);
14951510 }
lib/libcxx/include/future+41-51
......@@ -397,12 +397,14 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
397397# include <__type_traits/decay.h>
398398# include <__type_traits/enable_if.h>
399399# include <__type_traits/invoke.h>
400# include <__type_traits/is_constructible.h>
400401# include <__type_traits/is_same.h>
401402# include <__type_traits/remove_cvref.h>
402403# include <__type_traits/remove_reference.h>
403404# include <__type_traits/strip_signature.h>
404405# include <__type_traits/underlying_type.h>
405406# include <__utility/auto_cast.h>
407# include <__utility/exception_guard.h>
406408# include <__utility/forward.h>
407409# include <__utility/move.h>
408410# include <__utility/swap.h>
......@@ -477,13 +479,13 @@ inline _LIBCPP_HIDE_FROM_ABI launch& operator^=(launch& __x, launch __y) {
477479_LIBCPP_DECLARE_STRONG_ENUM(future_status){ready, timeout, deferred};
478480_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
479481
480_LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT;
482[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT;
481483
482inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(future_errc __e) _NOEXCEPT {
484[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(future_errc __e) _NOEXCEPT {
483485 return error_code(static_cast<int>(__e), future_category());
484486}
485487
486inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(future_errc __e) _NOEXCEPT {
488[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(future_errc __e) _NOEXCEPT {
487489 return error_condition(static_cast<int>(__e), future_category());
488490}
489491
......@@ -502,7 +504,7 @@ public:
502504 _LIBCPP_HIDE_FROM_ABI explicit future_error(future_errc __ec) : future_error(std::make_error_code(__ec)) {}
503505# endif
504506
505 _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
507 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
506508
507509 _LIBCPP_HIDE_FROM_ABI future_error(const future_error&) _NOEXCEPT = default;
508510 ~future_error() _NOEXCEPT override;
......@@ -583,12 +585,9 @@ inline future_status __assoc_sub_state::wait_for(const chrono::duration<_Rep, _P
583585template <class _Rp>
584586class _LIBCPP_HIDDEN __assoc_state : public __assoc_sub_state {
585587 typedef __assoc_sub_state base;
586 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
587 typedef typename aligned_storage<sizeof(_Rp), _LIBCPP_ALIGNOF(_Rp)>::type _Up;
588 _LIBCPP_SUPPRESS_DEPRECATED_POP
589588
590589protected:
591 _Up __value_;
590 _ALIGNAS_TYPE(_Rp) char __value_[sizeof(_Rp)];
592591
593592 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
594593
......@@ -943,15 +942,15 @@ public:
943942 }
944943
945944 _LIBCPP_HIDE_FROM_ABI ~future();
946 _LIBCPP_HIDE_FROM_ABI shared_future<_Rp> share() _NOEXCEPT;
945 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_future<_Rp> share() _NOEXCEPT;
947946
948947 // retrieving the value
949 _LIBCPP_HIDE_FROM_ABI _Rp get();
948 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Rp get();
950949
951950 _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
952951
953952 // functions to check state
954 _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
953 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
955954
956955 _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
957956 template <class _Rep, class _Period>
......@@ -1014,15 +1013,15 @@ public:
10141013 }
10151014
10161015 _LIBCPP_HIDE_FROM_ABI ~future();
1017 _LIBCPP_HIDE_FROM_ABI shared_future<_Rp&> share() _NOEXCEPT;
1016 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_future<_Rp&> share() _NOEXCEPT;
10181017
10191018 // retrieving the value
1020 _LIBCPP_HIDE_FROM_ABI _Rp& get();
1019 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Rp& get();
10211020
10221021 _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
10231022
10241023 // functions to check state
1025 _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
1024 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
10261025
10271026 _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
10281027 template <class _Rep, class _Period>
......@@ -1089,7 +1088,7 @@ public:
10891088 _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
10901089
10911090 // functions to check state
1092 _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
1091 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
10931092
10941093 _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
10951094 template <class _Rep, class _Period>
......@@ -1139,7 +1138,7 @@ public:
11391138 _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
11401139
11411140 // retrieving the result
1142 _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future();
1141 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future();
11431142
11441143 // setting the result
11451144 _LIBCPP_HIDE_FROM_ABI void set_value(const _Rp& __r);
......@@ -1256,7 +1255,7 @@ public:
12561255 _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
12571256
12581257 // retrieving the result
1259 _LIBCPP_HIDE_FROM_ABI future<_Rp&> get_future();
1258 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI future<_Rp&> get_future();
12601259
12611260 // setting the result
12621261 _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __r);
......@@ -1366,7 +1365,7 @@ public:
13661365 _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
13671366
13681367 // retrieving the result
1369 future<void> get_future();
1368 [[__nodiscard__]] future<void> get_future();
13701369
13711370 // setting the result
13721371 void set_value();
......@@ -1639,10 +1638,10 @@ public:
16391638 __p_.swap(__other.__p_);
16401639 }
16411640
1642 _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }
1641 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }
16431642
16441643 // result retrieval
1645 _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future() { return __p_.get_future(); }
1644 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future() { return __p_.get_future(); }
16461645
16471646 // execution
16481647 _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
......@@ -1728,10 +1727,10 @@ public:
17281727 __p_.swap(__other.__p_);
17291728 }
17301729
1731 _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }
1730 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }
17321731
17331732 // result retrieval
1734 _LIBCPP_HIDE_FROM_ABI future<void> get_future() { return __p_.get_future(); }
1733 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI future<void> get_future() { return __p_.get_future(); }
17351734
17361735 // execution
17371736 _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
......@@ -1815,16 +1814,9 @@ template <class _Rp, class _Fp>
18151814_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f) {
18161815 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> __h(
18171816 new __async_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
1818# if _LIBCPP_HAS_EXCEPTIONS
1819 try {
1820# endif
1821 std::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
1822# if _LIBCPP_HAS_EXCEPTIONS
1823 } catch (...) {
1824 __h->__make_ready();
1825 throw;
1826 }
1827# endif
1817 auto __guard = std::__make_exception_guard([&] { __h->__make_ready(); });
1818 std::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
1819 __guard.__complete();
18281820 return future<_Rp>(__h.get());
18291821}
18301822
......@@ -1837,20 +1829,16 @@ class _LIBCPP_HIDDEN __async_func {
18371829public:
18381830 using _Rp _LIBCPP_NODEBUG = __invoke_result_t<_Fp, _Args...>;
18391831
1840 _LIBCPP_HIDE_FROM_ABI explicit __async_func(_Fp&& __f, _Args&&... __args)
1841 : __f_(std::move(__f), std::move(__args)...) {}
1832 template <class _Gp, class... _BArgs>
1833 _LIBCPP_HIDE_FROM_ABI explicit __async_func(_Gp&& __g, _BArgs&&... __bargs)
1834 : __f_(std::forward<_Gp>(__g), std::forward<_BArgs>(__bargs)...) {}
18421835
18431836 _LIBCPP_HIDE_FROM_ABI __async_func(__async_func&& __f) : __f_(std::move(__f.__f_)) {}
18441837
18451838 _LIBCPP_HIDE_FROM_ABI _Rp operator()() {
1846 typedef typename __make_tuple_indices<1 + sizeof...(_Args), 1>::type _Index;
1847 return __execute(_Index());
1848 }
1849
1850private:
1851 template <size_t... _Indices>
1852 _LIBCPP_HIDE_FROM_ABI _Rp __execute(__tuple_indices<_Indices...>) {
1853 return std::__invoke(std::move(std::get<0>(__f_)), std::move(std::get<_Indices>(__f_))...);
1839 return [&]<size_t... _Indices>(__index_sequence<_Indices...>) -> _Rp {
1840 return std::__invoke(std::move(std::get<_Indices>(__f_))...);
1841 }(__index_sequence_for<_Fp, _Args...>{});
18541842 }
18551843};
18561844
......@@ -1861,6 +1849,10 @@ inline _LIBCPP_HIDE_FROM_ABI bool __does_policy_contain(launch __policy, launch
18611849template <class _Fp, class... _Args>
18621850[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI future<__invoke_result_t<__decay_t<_Fp>, __decay_t<_Args>...> >
18631851async(launch __policy, _Fp&& __f, _Args&&... __args) {
1852 static_assert(is_constructible<__decay_t<_Fp>, _Fp>::value, "");
1853 static_assert(_And<is_constructible<__decay_t<_Args>, _Args>...>::value, "");
1854 static_assert(__is_invocable_v<__decay_t<_Fp>, __decay_t<_Args>...>, "");
1855
18641856 typedef __async_func<__decay_t<_Fp>, __decay_t<_Args>...> _BF;
18651857 typedef typename _BF::_Rp _Rp;
18661858
......@@ -1868,8 +1860,7 @@ async(launch __policy, _Fp&& __f, _Args&&... __args) {
18681860 try {
18691861# endif
18701862 if (__does_policy_contain(__policy, launch::async))
1871 return std::__make_async_assoc_state<_Rp>(
1872 _BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)), _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...));
1863 return std::__make_async_assoc_state<_Rp>(_BF(std::forward<_Fp>(__f), std::forward<_Args>(__args)...));
18731864# if _LIBCPP_HAS_EXCEPTIONS
18741865 } catch (...) {
18751866 if (__policy == launch::async)
......@@ -1878,8 +1869,7 @@ async(launch __policy, _Fp&& __f, _Args&&... __args) {
18781869# endif
18791870
18801871 if (__does_policy_contain(__policy, launch::deferred))
1881 return std::__make_deferred_assoc_state<_Rp>(
1882 _BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)), _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...));
1872 return std::__make_deferred_assoc_state<_Rp>(_BF(std::forward<_Fp>(__f), std::forward<_Args>(__args)...));
18831873 return future<_Rp>{};
18841874}
18851875
......@@ -1915,12 +1905,12 @@ public:
19151905 }
19161906
19171907 // retrieving the value
1918 _LIBCPP_HIDE_FROM_ABI const _Rp& get() const { return __state_->copy(); }
1908 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const _Rp& get() const { return __state_->copy(); }
19191909
19201910 _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
19211911
19221912 // functions to check state
1923 _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
1913 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
19241914
19251915 _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
19261916 template <class _Rep, class _Period>
......@@ -1971,12 +1961,12 @@ public:
19711961 }
19721962
19731963 // retrieving the value
1974 _LIBCPP_HIDE_FROM_ABI _Rp& get() const { return __state_->copy(); }
1964 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Rp& get() const { return __state_->copy(); }
19751965
19761966 _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
19771967
19781968 // functions to check state
1979 _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
1969 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
19801970
19811971 _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
19821972 template <class _Rep, class _Period>
......@@ -2032,7 +2022,7 @@ public:
20322022 _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
20332023
20342024 // functions to check state
2035 _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
2025 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
20362026
20372027 _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
20382028 template <class _Rep, class _Period>
lib/libcxx/include/initializer_list+9-3
......@@ -78,11 +78,17 @@ public:
7878
7979 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 initializer_list() _NOEXCEPT : __begin_(nullptr), __size_(0) {}
8080
81 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t size() const _NOEXCEPT { return __size_; }
81 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t size() const _NOEXCEPT {
82 return __size_;
83 }
8284
83 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* begin() const _NOEXCEPT { return __begin_; }
85 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* begin() const _NOEXCEPT {
86 return __begin_;
87 }
8488
85 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* end() const _NOEXCEPT { return __begin_ + __size_; }
89 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* end() const _NOEXCEPT {
90 return __begin_ + __size_;
91 }
8692};
8793
8894template <class _Ep>
lib/libcxx/include/inttypes.h+16-16
......@@ -236,33 +236,33 @@ uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int
236236*/
237237
238238#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
239# include <__cxx03/inttypes.h>
239# include <__cxx03/__config>
240240#else
241241# include <__config>
242#endif
242243
243# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
244# pragma GCC system_header
245# endif
244#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
245# pragma GCC system_header
246#endif
246247
247248/* C99 stdlib (e.g. glibc < 2.18) does not provide format macros needed
248249 for C++11 unless __STDC_FORMAT_MACROS is defined
249250*/
250# if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS)
251# define __STDC_FORMAT_MACROS
252# endif
251#if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS)
252# define __STDC_FORMAT_MACROS
253#endif
253254
254# if __has_include_next(<inttypes.h>)
255# include_next <inttypes.h>
256# endif
255#if __has_include_next(<inttypes.h>)
256# include_next <inttypes.h>
257#endif
257258
258# ifdef __cplusplus
259#ifdef __cplusplus
259260
260# include <stdint.h>
261# include <stdint.h>
261262
262# undef imaxabs
263# undef imaxdiv
263# undef imaxabs
264# undef imaxdiv
264265
265# endif // __cplusplus
266#endif // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
266#endif // __cplusplus
267267
268268#endif // _LIBCPP_INTTYPES_H
lib/libcxx/include/ios+28-28
......@@ -305,25 +305,25 @@ public:
305305 class _LIBCPP_EXPORTED_FROM_ABI Init;
306306
307307 // 27.5.2.2 fmtflags state:
308 _LIBCPP_HIDE_FROM_ABI fmtflags flags() const;
308 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI fmtflags flags() const;
309309 _LIBCPP_HIDE_FROM_ABI fmtflags flags(fmtflags __fmtfl);
310310 _LIBCPP_HIDE_FROM_ABI fmtflags setf(fmtflags __fmtfl);
311311 _LIBCPP_HIDE_FROM_ABI fmtflags setf(fmtflags __fmtfl, fmtflags __mask);
312312 _LIBCPP_HIDE_FROM_ABI void unsetf(fmtflags __mask);
313313
314 _LIBCPP_HIDE_FROM_ABI streamsize precision() const;
314 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI streamsize precision() const;
315315 _LIBCPP_HIDE_FROM_ABI streamsize precision(streamsize __prec);
316 _LIBCPP_HIDE_FROM_ABI streamsize width() const;
316 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI streamsize width() const;
317317 _LIBCPP_HIDE_FROM_ABI streamsize width(streamsize __wide);
318318
319319 // 27.5.2.3 locales:
320320 locale imbue(const locale& __loc);
321 locale getloc() const;
321 [[__nodiscard__]] locale getloc() const;
322322
323323 // 27.5.2.5 storage:
324 static int xalloc();
325 long& iword(int __index);
326 void*& pword(int __index);
324 [[__nodiscard__]] static int xalloc();
325 [[__nodiscard__]] long& iword(int __index);
326 [[__nodiscard__]] void*& pword(int __index);
327327
328328 // destructor
329329 virtual ~ios_base();
......@@ -338,16 +338,16 @@ public:
338338
339339 static bool sync_with_stdio(bool __sync = true);
340340
341 _LIBCPP_HIDE_FROM_ABI iostate rdstate() const;
341 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iostate rdstate() const;
342342 void clear(iostate __state = goodbit);
343343 _LIBCPP_HIDE_FROM_ABI void setstate(iostate __state);
344344
345 _LIBCPP_HIDE_FROM_ABI bool good() const;
346 _LIBCPP_HIDE_FROM_ABI bool eof() const;
347 _LIBCPP_HIDE_FROM_ABI bool fail() const;
348 _LIBCPP_HIDE_FROM_ABI bool bad() const;
345 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool good() const;
346 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool eof() const;
347 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool fail() const;
348 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool bad() const;
349349
350 _LIBCPP_HIDE_FROM_ABI iostate exceptions() const;
350 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iostate exceptions() const;
351351 _LIBCPP_HIDE_FROM_ABI void exceptions(iostate __iostate);
352352
353353 void __set_badbit_and_consider_rethrow();
......@@ -425,13 +425,13 @@ template <>
425425struct is_error_code_enum<io_errc::__lx> : public true_type {};
426426# endif
427427
428_LIBCPP_EXPORTED_FROM_ABI const error_category& iostream_category() _NOEXCEPT;
428[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& iostream_category() _NOEXCEPT;
429429
430inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(io_errc __e) _NOEXCEPT {
430[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(io_errc __e) _NOEXCEPT {
431431 return error_code(static_cast<int>(__e), iostream_category());
432432}
433433
434inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(io_errc __e) _NOEXCEPT {
434[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(io_errc __e) _NOEXCEPT {
435435 return error_condition(static_cast<int>(__e), iostream_category());
436436}
437437
......@@ -580,16 +580,16 @@ public:
580580 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const { return !fail(); }
581581# endif
582582
583 _LIBCPP_HIDE_FROM_ABI bool operator!() const { return fail(); }
584 _LIBCPP_HIDE_FROM_ABI iostate rdstate() const { return ios_base::rdstate(); }
583 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool operator!() const { return fail(); }
584 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iostate rdstate() const { return ios_base::rdstate(); }
585585 _LIBCPP_HIDE_FROM_ABI void clear(iostate __state = goodbit) { ios_base::clear(__state); }
586586 _LIBCPP_HIDE_FROM_ABI void setstate(iostate __state) { ios_base::setstate(__state); }
587 _LIBCPP_HIDE_FROM_ABI bool good() const { return ios_base::good(); }
588 _LIBCPP_HIDE_FROM_ABI bool eof() const { return ios_base::eof(); }
589 _LIBCPP_HIDE_FROM_ABI bool fail() const { return ios_base::fail(); }
590 _LIBCPP_HIDE_FROM_ABI bool bad() const { return ios_base::bad(); }
587 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool good() const { return ios_base::good(); }
588 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool eof() const { return ios_base::eof(); }
589 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool fail() const { return ios_base::fail(); }
590 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool bad() const { return ios_base::bad(); }
591591
592 _LIBCPP_HIDE_FROM_ABI iostate exceptions() const { return ios_base::exceptions(); }
592 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iostate exceptions() const { return ios_base::exceptions(); }
593593 _LIBCPP_HIDE_FROM_ABI void exceptions(iostate __iostate) { ios_base::exceptions(__iostate); }
594594
595595 // 27.5.4.1 Constructor/destructor:
......@@ -597,21 +597,21 @@ public:
597597 ~basic_ios() override;
598598
599599 // 27.5.4.2 Members:
600 _LIBCPP_HIDE_FROM_ABI basic_ostream<char_type, traits_type>* tie() const;
600 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_ostream<char_type, traits_type>* tie() const;
601601 _LIBCPP_HIDE_FROM_ABI basic_ostream<char_type, traits_type>* tie(basic_ostream<char_type, traits_type>* __tiestr);
602602
603 _LIBCPP_HIDE_FROM_ABI basic_streambuf<char_type, traits_type>* rdbuf() const;
603 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_streambuf<char_type, traits_type>* rdbuf() const;
604604 _LIBCPP_HIDE_FROM_ABI basic_streambuf<char_type, traits_type>* rdbuf(basic_streambuf<char_type, traits_type>* __sb);
605605
606606 basic_ios& copyfmt(const basic_ios& __rhs);
607607
608 _LIBCPP_HIDE_FROM_ABI char_type fill() const;
608 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char_type fill() const;
609609 _LIBCPP_HIDE_FROM_ABI char_type fill(char_type __ch);
610610
611611 _LIBCPP_HIDE_FROM_ABI locale imbue(const locale& __loc);
612612
613 _LIBCPP_HIDE_FROM_ABI char narrow(char_type __c, char __dfault) const;
614 _LIBCPP_HIDE_FROM_ABI char_type widen(char __c) const;
613 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char narrow(char_type __c, char __dfault) const;
614 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char_type widen(char __c) const;
615615
616616protected:
617617 _LIBCPP_HIDE_FROM_ABI basic_ios() {
lib/libcxx/include/istream+19-13
......@@ -70,6 +70,7 @@ public:
7070 basic_istream& getline(char_type* s, streamsize n, char_type delim);
7171
7272 basic_istream& ignore(streamsize n = 1, int_type delim = traits_type::eof());
73 basic_istream& ignore(streamsize n, char_type delim); // Since C++26, implemented as a DR
7374 int_type peek();
7475 basic_istream& read (char_type* s, streamsize n);
7576 streamsize readsome(char_type* s, streamsize n);
......@@ -172,6 +173,7 @@ template <class Stream, class T>
172173# include <__type_traits/conjunction.h>
173174# include <__type_traits/enable_if.h>
174175# include <__type_traits/is_base_of.h>
176# include <__type_traits/is_same.h>
175177# include <__type_traits/make_unsigned.h>
176178# include <__utility/declval.h>
177179# include <__utility/forward.h>
......@@ -207,7 +209,7 @@ public:
207209 typedef typename traits_type::off_type off_type;
208210
209211 // 27.7.1.1.1 Constructor/destructor:
210 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb)
212 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb)
211213 : __gc_(0) {
212214 this->init(__sb);
213215 }
......@@ -219,7 +221,7 @@ protected:
219221 // 27.7.1.1.2 Assign/swap:
220222 inline _LIBCPP_HIDE_FROM_ABI basic_istream& operator=(basic_istream&& __rhs);
221223
222 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void swap(basic_istream& __rhs) {
224 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void swap(basic_istream& __rhs) {
223225 std::swap(__gc_, __rhs.__gc_);
224226 basic_ios<char_type, traits_type>::swap(__rhs);
225227 }
......@@ -232,17 +234,17 @@ public:
232234 class sentry;
233235
234236 // 27.7.1.2 Formatted input:
235 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&)) {
237 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&)) {
236238 return __pf(*this);
237239 }
238240
239 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream&
241 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream&
240242 operator>>(basic_ios<char_type, traits_type>& (*__pf)(basic_ios<char_type, traits_type>&)) {
241243 __pf(*this);
242244 return *this;
243245 }
244246
245 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& operator>>(ios_base& (*__pf)(ios_base&)) {
247 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream& operator>>(ios_base& (*__pf)(ios_base&)) {
246248 __pf(*this);
247249 return *this;
248250 }
......@@ -263,35 +265,39 @@ public:
263265 basic_istream& operator>>(void*& __p);
264266
265267 // 27.7.1.3 Unformatted input:
266 _LIBCPP_HIDE_FROM_ABI streamsize gcount() const { return __gc_; }
268 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI streamsize gcount() const { return __gc_; }
267269 int_type get();
268270
269 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(char_type& __c) {
271 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream& get(char_type& __c) {
270272 int_type __ch = get();
271273 if (__ch != traits_type::eof())
272274 __c = traits_type::to_char_type(__ch);
273275 return *this;
274276 }
275277
276 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(char_type* __s, streamsize __n) {
278 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream& get(char_type* __s, streamsize __n) {
277279 return get(__s, __n, this->widen('\n'));
278280 }
279281
280282 basic_istream& get(char_type* __s, streamsize __n, char_type __dlm);
281283
282 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(basic_streambuf<char_type, traits_type>& __sb) {
284 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream& get(basic_streambuf<char_type, traits_type>& __sb) {
283285 return get(__sb, this->widen('\n'));
284286 }
285287
286288 basic_istream& get(basic_streambuf<char_type, traits_type>& __sb, char_type __dlm);
287289
288 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& getline(char_type* __s, streamsize __n) {
290 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream& getline(char_type* __s, streamsize __n) {
289291 return getline(__s, __n, this->widen('\n'));
290292 }
291293
292294 basic_istream& getline(char_type* __s, streamsize __n, char_type __dlm);
293295
294296 basic_istream& ignore(streamsize __n = 1, int_type __dlm = traits_type::eof());
297 template <class _Tp = char_type, __enable_if_t<is_same<_Tp, char>::value, int> = 0>
298 _LIBCPP_HIDE_FROM_ABI basic_istream& ignore(streamsize __n, char_type __delim) {
299 return ignore(__n, traits_type::to_int_type(__delim));
300 }
295301 int_type peek();
296302 basic_istream& read(char_type* __s, streamsize __n);
297303 streamsize readsome(char_type* __s, streamsize __n);
......@@ -300,7 +306,7 @@ public:
300306 basic_istream& unget();
301307 int sync();
302308
303 pos_type tellg();
309 [[__nodiscard__]] pos_type tellg();
304310 basic_istream& seekg(pos_type __pos);
305311 basic_istream& seekg(off_type __off, ios_base::seekdir __dir);
306312};
......@@ -1178,7 +1184,7 @@ public:
11781184 typedef typename traits_type::off_type off_type;
11791185
11801186 // constructor/destructor
1181 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb)
1187 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb)
11821188 : basic_istream<_CharT, _Traits>(__sb) {}
11831189
11841190 ~basic_iostream() override;
......@@ -1189,7 +1195,7 @@ protected:
11891195 // assign/swap
11901196 inline _LIBCPP_HIDE_FROM_ABI basic_iostream& operator=(basic_iostream&& __rhs);
11911197
1192 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void swap(basic_iostream& __rhs) {
1198 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void swap(basic_iostream& __rhs) {
11931199 basic_istream<char_type, traits_type>::swap(__rhs);
11941200 }
11951201};
lib/libcxx/include/iterator+10
......@@ -737,6 +737,16 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
737737# include <compare>
738738# include <concepts>
739739
740// [range.access.general]
741# if _LIBCPP_STD_VER >= 20
742# include <__ranges/access.h>
743# include <__ranges/data.h>
744# include <__ranges/empty.h>
745# include <__ranges/rbegin.h>
746# include <__ranges/rend.h>
747# include <__ranges/size.h>
748# endif
749
740750# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
741751# pragma GCC system_header
742752# endif
lib/libcxx/include/latch+7-5
......@@ -70,7 +70,9 @@ class latch {
7070 atomic<ptrdiff_t> __a_;
7171
7272public:
73 static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { return numeric_limits<ptrdiff_t>::max(); }
73 [[nodiscard]] static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {
74 return numeric_limits<ptrdiff_t>::max();
75 }
7476
7577 inline _LIBCPP_HIDE_FROM_ABI constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected) {
7678 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
......@@ -87,7 +89,7 @@ public:
8789 latch(const latch&) = delete;
8890 latch& operator=(const latch&) = delete;
8991
90 inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void count_down(ptrdiff_t __update = 1) {
92 inline _LIBCPP_HIDE_FROM_ABI void count_down(ptrdiff_t __update = 1) {
9193 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__update >= 0, "latch::count_down called with a negative value");
9294 auto const __old = __a_.fetch_sub(__update, memory_order_release);
9395 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
......@@ -97,16 +99,16 @@ public:
9799 if (__old == __update)
98100 __a_.notify_all();
99101 }
100 inline _LIBCPP_HIDE_FROM_ABI bool try_wait() const noexcept {
102 [[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool try_wait() const noexcept {
101103 auto __value = __a_.load(memory_order_acquire);
102104 return try_wait_impl(__value);
103105 }
104 inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait() const {
106 inline _LIBCPP_HIDE_FROM_ABI void wait() const {
105107 std::__atomic_wait_unless(__a_, memory_order_acquire, [this](ptrdiff_t& __value) -> bool {
106108 return try_wait_impl(__value);
107109 });
108110 }
109 inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void arrive_and_wait(ptrdiff_t __update = 1) {
111 inline _LIBCPP_HIDE_FROM_ABI void arrive_and_wait(ptrdiff_t __update = 1) {
110112 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__update >= 0, "latch::arrive_and_wait called with a negative value");
111113 // other preconditions on __update are checked in count_down()
112114
lib/libcxx/include/limits+4-4
......@@ -107,7 +107,7 @@ template<> class numeric_limits<cv long double>;
107107#else
108108# include <__config>
109109# include <__type_traits/is_arithmetic.h>
110# include <__type_traits/is_signed.h>
110# include <__type_traits/is_same.h>
111111
112112# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
113113# pragma GCC system_header
......@@ -217,10 +217,10 @@ protected:
217217
218218 static _LIBCPP_CONSTEXPR const bool is_iec559 = false;
219219 static _LIBCPP_CONSTEXPR const bool is_bounded = true;
220 static _LIBCPP_CONSTEXPR const bool is_modulo = !std::is_signed<_Tp>::value;
220 static _LIBCPP_CONSTEXPR const bool is_modulo = !is_signed;
221221
222# if defined(__i386__) || defined(__x86_64__) || defined(__pnacl__) || defined(__wasm__)
223 static _LIBCPP_CONSTEXPR const bool traps = true;
222# if defined(__i386__) || defined(__x86_64__) || defined(__wasm__)
223 static _LIBCPP_CONSTEXPR const bool traps = is_same<decltype(+_Tp(0)), _Tp>::value;
224224# else
225225 static _LIBCPP_CONSTEXPR const bool traps = false;
226226# endif
lib/libcxx/include/list+61-79
......@@ -228,15 +228,14 @@ template <class T, class Allocator, class Predicate>
228228# include <__ranges/concepts.h>
229229# include <__ranges/container_compatible_range.h>
230230# include <__ranges/from_range.h>
231# include <__type_traits/conditional.h>
232231# include <__type_traits/container_traits.h>
233232# include <__type_traits/enable_if.h>
234233# include <__type_traits/is_allocator.h>
235234# include <__type_traits/is_nothrow_assignable.h>
236235# include <__type_traits/is_nothrow_constructible.h>
237# include <__type_traits/is_pointer.h>
238236# include <__type_traits/is_same.h>
239237# include <__type_traits/type_identity.h>
238# include <__utility/exception_guard.h>
240239# include <__utility/forward.h>
241240# include <__utility/move.h>
242241# include <__utility/swap.h>
......@@ -275,17 +274,6 @@ template <class _Tp, class _VoidPtr>
275274struct __list_node_pointer_traits {
276275 typedef __rebind_pointer_t<_VoidPtr, __list_node<_Tp, _VoidPtr> > __node_pointer;
277276 typedef __rebind_pointer_t<_VoidPtr, __list_node_base<_Tp, _VoidPtr> > __base_pointer;
278
279// TODO(LLVM 22): Remove this check
280# ifndef _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB
281 static_assert(sizeof(__node_pointer) == sizeof(__node_pointer) && _LIBCPP_ALIGNOF(__base_pointer) ==
282 _LIBCPP_ALIGNOF(__node_pointer),
283 "It looks like you are using std::list with a fancy pointer type that thas a different representation "
284 "depending on whether it points to a list base pointer or a list node pointer (both of which are "
285 "implementation details of the standard library). This means that your ABI is being broken between "
286 "LLVM 19 and LLVM 20. If you don't care about your ABI being broken, define the "
287 "_LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB macro to silence this diagnostic.");
288# endif
289277};
290278
291279template <class _Tp, class _VoidPtr>
......@@ -724,7 +712,7 @@ public:
724712 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n, const allocator_type& __a);
725713# endif
726714 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list(size_type __n, const value_type& __x);
727 template <__enable_if_t<__is_allocator<_Alloc>::value, int> = 0>
715 template <__enable_if_t<__is_allocator_v<_Alloc>, int> = 0>
728716 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI
729717 list(size_type __n, const value_type& __x, const allocator_type& __a)
730718 : __base(__a) {
......@@ -786,57 +774,71 @@ public:
786774
787775 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __x);
788776
789 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT;
777 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT;
790778
791 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return this->__size_; }
779 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
780 return this->__size_;
781 }
792782 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
793783 return __base::empty();
794784 }
795 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
785 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
796786 return std::min<size_type>(this->__node_alloc_max_size(), numeric_limits<difference_type >::max());
797787 }
798788
799 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __base::begin(); }
800 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __base::begin(); }
801 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __base::end(); }
802 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __base::end(); }
803 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
789 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
790 return __base::begin();
791 }
792 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
793 return __base::begin();
794 }
795 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
796 return __base::end();
797 }
798 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
799 return __base::end();
800 }
801 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
804802 return __base::begin();
805803 }
806 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __base::end(); }
804 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
805 return __base::end();
806 }
807807
808 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT {
808 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT {
809809 return reverse_iterator(end());
810810 }
811 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
811 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator
812 rbegin() const _NOEXCEPT {
812813 return const_reverse_iterator(end());
813814 }
814 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT {
815 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT {
815816 return reverse_iterator(begin());
816817 }
817 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
818 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
818819 return const_reverse_iterator(begin());
819820 }
820 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT {
821 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator
822 crbegin() const _NOEXCEPT {
821823 return const_reverse_iterator(end());
822824 }
823 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {
825 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {
824826 return const_reverse_iterator(begin());
825827 }
826828
827 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() {
829 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() {
828830 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list");
829831 return __base::__end_.__next_->__as_node()->__get_value();
830832 }
831 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const {
833 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const {
832834 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list");
833835 return __base::__end_.__next_->__as_node()->__get_value();
834836 }
835 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference back() {
837 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference back() {
836838 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list");
837839 return __base::__end_.__prev_->__as_node()->__get_value();
838840 }
839 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference back() const {
841 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference back() const {
840842 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list");
841843 return __base::__end_.__prev_->__as_node()->__get_value();
842844 }
......@@ -1000,22 +1002,22 @@ private:
10001002
10011003# if _LIBCPP_STD_VER >= 17
10021004template <class _InputIterator,
1003 class _Alloc = allocator<__iter_value_type<_InputIterator>>,
1005 class _Alloc = allocator<__iterator_value_type<_InputIterator>>,
10041006 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1005 class = enable_if_t<__is_allocator<_Alloc>::value> >
1006list(_InputIterator, _InputIterator) -> list<__iter_value_type<_InputIterator>, _Alloc>;
1007 class = enable_if_t<__is_allocator_v<_Alloc>>>
1008list(_InputIterator, _InputIterator) -> list<__iterator_value_type<_InputIterator>, _Alloc>;
10071009
10081010template <class _InputIterator,
10091011 class _Alloc,
10101012 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1011 class = enable_if_t<__is_allocator<_Alloc>::value> >
1012list(_InputIterator, _InputIterator, _Alloc) -> list<__iter_value_type<_InputIterator>, _Alloc>;
1013 class = enable_if_t<__is_allocator_v<_Alloc>>>
1014list(_InputIterator, _InputIterator, _Alloc) -> list<__iterator_value_type<_InputIterator>, _Alloc>;
10131015# endif
10141016
10151017# if _LIBCPP_STD_VER >= 23
10161018template <ranges::input_range _Range,
10171019 class _Alloc = allocator<ranges::range_value_t<_Range>>,
1018 class = enable_if_t<__is_allocator<_Alloc>::value> >
1020 class = enable_if_t<__is_allocator_v<_Alloc>>>
10191021list(from_range_t, _Range&&, _Alloc = _Alloc()) -> list<ranges::range_value_t<_Range>, _Alloc>;
10201022# endif
10211023
......@@ -1233,14 +1235,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
12331235 ++__ds;
12341236 __r = iterator(__node->__as_link());
12351237 iterator __e = __r;
1236# if _LIBCPP_HAS_EXCEPTIONS
1237 try {
1238# endif // _LIBCPP_HAS_EXCEPTIONS
1239 for (--__n; __n != 0; --__n, (void)++__e, ++__ds) {
1240 __e.__ptr_->__next_ = this->__create_node(/* prev = */ __e.__ptr_, /* next = */ nullptr, __x)->__as_link();
1241 }
1242# if _LIBCPP_HAS_EXCEPTIONS
1243 } catch (...) {
1238 auto __guard = std::__make_exception_guard([&] {
12441239 while (true) {
12451240 __base_pointer __prev = __e.__ptr_->__prev_;
12461241 __node_pointer __current = __e.__ptr_->__as_node();
......@@ -1249,9 +1244,11 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
12491244 break;
12501245 __e = iterator(__prev);
12511246 }
1252 throw;
1247 });
1248 for (--__n; __n != 0; --__n, (void)++__e, ++__ds) {
1249 __e.__ptr_->__next_ = this->__create_node(/* prev = */ __e.__ptr_, /* next = */ nullptr, __x)->__as_link();
12531250 }
1254# endif // _LIBCPP_HAS_EXCEPTIONS
1251 __guard.__complete();
12551252 __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);
12561253 this->__size_ += __ds;
12571254 }
......@@ -1276,14 +1273,7 @@ list<_Tp, _Alloc>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Se
12761273 ++__ds;
12771274 __r = iterator(__node->__as_link());
12781275 iterator __e = __r;
1279# if _LIBCPP_HAS_EXCEPTIONS
1280 try {
1281# endif // _LIBCPP_HAS_EXCEPTIONS
1282 for (++__f; __f != __l; ++__f, (void)++__e, ++__ds) {
1283 __e.__ptr_->__next_ = this->__create_node(/* prev = */ __e.__ptr_, /* next = */ nullptr, *__f)->__as_link();
1284 }
1285# if _LIBCPP_HAS_EXCEPTIONS
1286 } catch (...) {
1276 auto __guard = std::__make_exception_guard([&] {
12871277 while (true) {
12881278 __base_pointer __prev = __e.__ptr_->__prev_;
12891279 __node_pointer __current = __e.__ptr_->__as_node();
......@@ -1292,9 +1282,11 @@ list<_Tp, _Alloc>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Se
12921282 break;
12931283 __e = iterator(__prev);
12941284 }
1295 throw;
1285 });
1286 for (++__f; __f != __l; ++__f, (void)++__e, ++__ds) {
1287 __e.__ptr_->__next_ = this->__create_node(/* prev = */ __e.__ptr_, /* next = */ nullptr, *__f)->__as_link();
12961288 }
1297# endif // _LIBCPP_HAS_EXCEPTIONS
1289 __guard.__complete();
12981290 __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);
12991291 this->__size_ += __ds;
13001292 }
......@@ -1452,14 +1444,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::resize(size_type __n) {
14521444 ++__ds;
14531445 iterator __r = iterator(__node->__as_link());
14541446 iterator __e = __r;
1455# if _LIBCPP_HAS_EXCEPTIONS
1456 try {
1457# endif // _LIBCPP_HAS_EXCEPTIONS
1458 for (--__n; __n != 0; --__n, (void)++__e, ++__ds) {
1459 __e.__ptr_->__next_ = this->__create_node(/* prev = */ __e.__ptr_, /* next = */ nullptr)->__as_link();
1460 }
1461# if _LIBCPP_HAS_EXCEPTIONS
1462 } catch (...) {
1447 auto __guard = std::__make_exception_guard([&] {
14631448 while (true) {
14641449 __base_pointer __prev = __e.__ptr_->__prev_;
14651450 __node_pointer __current = __e.__ptr_->__as_node();
......@@ -1468,9 +1453,11 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::resize(size_type __n) {
14681453 break;
14691454 __e = iterator(__prev);
14701455 }
1471 throw;
1456 });
1457 for (--__n; __n != 0; --__n, (void)++__e, ++__ds) {
1458 __e.__ptr_->__next_ = this->__create_node(/* prev = */ __e.__ptr_, /* next = */ nullptr)->__as_link();
14721459 }
1473# endif // _LIBCPP_HAS_EXCEPTIONS
1460 __guard.__complete();
14741461 __link_nodes_at_back(__r.__ptr_, __e.__ptr_);
14751462 this->__size_ += __ds;
14761463 }
......@@ -1488,14 +1475,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::resize(size_type __n, cons
14881475 __base_pointer __nl = __node->__as_link();
14891476 iterator __r = iterator(__nl);
14901477 iterator __e = __r;
1491# if _LIBCPP_HAS_EXCEPTIONS
1492 try {
1493# endif // _LIBCPP_HAS_EXCEPTIONS
1494 for (--__n; __n != 0; --__n, (void)++__e, ++__ds) {
1495 __e.__ptr_->__next_ = this->__create_node(/* prev = */ __e.__ptr_, /* next = */ nullptr, __x)->__as_link();
1496 }
1497# if _LIBCPP_HAS_EXCEPTIONS
1498 } catch (...) {
1478 auto __guard = std::__make_exception_guard([&] {
14991479 while (true) {
15001480 __base_pointer __prev = __e.__ptr_->__prev_;
15011481 __node_pointer __current = __e.__ptr_->__as_node();
......@@ -1504,9 +1484,11 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::resize(size_type __n, cons
15041484 break;
15051485 __e = iterator(__prev);
15061486 }
1507 throw;
1487 });
1488 for (--__n; __n != 0; --__n, (void)++__e, ++__ds) {
1489 __e.__ptr_->__next_ = this->__create_node(/* prev = */ __e.__ptr_, /* next = */ nullptr, __x)->__as_link();
15081490 }
1509# endif // _LIBCPP_HAS_EXCEPTIONS
1491 __guard.__complete();
15101492 __link_nodes(__base::__end_as_link(), __r.__ptr_, __e.__ptr_);
15111493 this->__size_ += __ds;
15121494 }
lib/libcxx/include/map+386-274
......@@ -577,12 +577,12 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
577577# include <__algorithm/equal.h>
578578# include <__algorithm/lexicographical_compare.h>
579579# include <__algorithm/lexicographical_compare_three_way.h>
580# include <__algorithm/specialized_algorithms.h>
580581# include <__assert>
581582# include <__config>
582583# include <__functional/binary_function.h>
583584# include <__functional/is_transparent.h>
584585# include <__functional/operations.h>
585# include <__fwd/map.h>
586586# include <__iterator/erase_if_container.h>
587587# include <__iterator/iterator_traits.h>
588588# include <__iterator/ranges_iterator_traits.h>
......@@ -590,19 +590,23 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
590590# include <__memory/addressof.h>
591591# include <__memory/allocator.h>
592592# include <__memory/allocator_traits.h>
593# include <__memory/compressed_pair.h>
593594# include <__memory/pointer_traits.h>
594595# include <__memory/unique_ptr.h>
595596# include <__memory_resource/polymorphic_allocator.h>
596597# include <__node_handle>
598# include <__ranges/access.h>
597599# include <__ranges/concepts.h>
598600# include <__ranges/container_compatible_range.h>
599601# include <__ranges/from_range.h>
600602# include <__tree>
601603# include <__type_traits/container_traits.h>
602604# include <__type_traits/is_allocator.h>
605# include <__type_traits/make_transparent.h>
603606# include <__type_traits/remove_const.h>
604607# include <__type_traits/type_identity.h>
605608# include <__utility/forward.h>
609# include <__utility/lazy_synth_three_way_comparator.h>
606610# include <__utility/pair.h>
607611# include <__utility/piecewise_construct.h>
608612# include <__utility/swap.h>
......@@ -632,47 +636,9 @@ _LIBCPP_PUSH_MACROS
632636
633637_LIBCPP_BEGIN_NAMESPACE_STD
634638
635template <class _Key,
636 class _CP,
637 class _Compare,
638 bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value>
639class __map_value_compare : private _Compare {
640public:
641 _LIBCPP_HIDE_FROM_ABI __map_value_compare() _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
642 : _Compare() {}
643 _LIBCPP_HIDE_FROM_ABI __map_value_compare(_Compare __c) _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
644 : _Compare(__c) {}
645 _LIBCPP_HIDE_FROM_ABI const _Compare& key_comp() const _NOEXCEPT { return *this; }
646 _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _CP& __y) const {
647 return static_cast<const _Compare&>(*this)(__x.first, __y.first);
648 }
649 _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const {
650 return static_cast<const _Compare&>(*this)(__x.first, __y);
651 }
652 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const {
653 return static_cast<const _Compare&>(*this)(__x, __y.first);
654 }
655 _LIBCPP_HIDE_FROM_ABI void swap(__map_value_compare& __y) _NOEXCEPT_(__is_nothrow_swappable_v<_Compare>) {
656 using std::swap;
657 swap(static_cast<_Compare&>(*this), static_cast<_Compare&>(__y));
658 }
659
660# if _LIBCPP_STD_VER >= 14
661 template <typename _K2>
662 _LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _CP& __y) const {
663 return static_cast<const _Compare&>(*this)(__x, __y.first);
664 }
665
666 template <typename _K2>
667 _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _K2& __y) const {
668 return static_cast<const _Compare&>(*this)(__x.first, __y);
669 }
670# endif
671};
672
673639template <class _Key, class _CP, class _Compare>
674class __map_value_compare<_Key, _CP, _Compare, false> {
675 _Compare __comp_;
640class __map_value_compare {
641 _LIBCPP_COMPRESSED_ELEMENT(_Compare, __comp_);
676642
677643public:
678644 _LIBCPP_HIDE_FROM_ABI __map_value_compare() _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
......@@ -684,7 +650,7 @@ public:
684650 _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _CP& __y) const { return __comp_(__x.first, __y.first); }
685651 _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const { return __comp_(__x.first, __y); }
686652 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const { return __comp_(__x, __y.first); }
687 void swap(__map_value_compare& __y) _NOEXCEPT_(__is_nothrow_swappable_v<_Compare>) {
653 _LIBCPP_HIDE_FROM_ABI void swap(__map_value_compare& __y) _NOEXCEPT_(__is_nothrow_swappable_v<_Compare>) {
688654 using std::swap;
689655 swap(__comp_, __y.__comp_);
690656 }
......@@ -702,9 +668,58 @@ public:
702668# endif
703669};
704670
705template <class _Key, class _CP, class _Compare, bool __b>
671template <class _Key, class _MapValueT, class _Compare>
672struct __make_transparent<_Key, __map_value_compare<_Key, _MapValueT, _Compare> > {
673 using type _LIBCPP_NODEBUG = __map_value_compare<_Key, _MapValueT, __make_transparent_t<_Key, _Compare> >;
674};
675
676# if _LIBCPP_STD_VER >= 14
677template <class _MapValueT, class _Key, class _Compare>
678struct __lazy_synth_three_way_comparator<__map_value_compare<_Key, _MapValueT, _Compare>, _MapValueT, _MapValueT> {
679 __lazy_synth_three_way_comparator<_Compare, _Key, _Key> __comp_;
680
681 __lazy_synth_three_way_comparator(
682 _LIBCPP_CTOR_LIFETIMEBOUND const __map_value_compare<_Key, _MapValueT, _Compare>& __comp)
683 : __comp_(__comp.key_comp()) {}
684
685 _LIBCPP_HIDE_FROM_ABI auto
686 operator()(_LIBCPP_LIFETIMEBOUND const _MapValueT& __lhs, _LIBCPP_LIFETIMEBOUND const _MapValueT& __rhs) const {
687 return __comp_(__lhs.first, __rhs.first);
688 }
689};
690
691template <class _MapValueT, class _Key, class _TransparentKey, class _Compare>
692struct __lazy_synth_three_way_comparator<__map_value_compare<_Key, _MapValueT, _Compare>, _TransparentKey, _MapValueT> {
693 __lazy_synth_three_way_comparator<_Compare, _TransparentKey, _Key> __comp_;
694
695 __lazy_synth_three_way_comparator(
696 _LIBCPP_CTOR_LIFETIMEBOUND const __map_value_compare<_Key, _MapValueT, _Compare>& __comp)
697 : __comp_(__comp.key_comp()) {}
698
699 _LIBCPP_HIDE_FROM_ABI auto
700 operator()(_LIBCPP_LIFETIMEBOUND const _TransparentKey& __lhs, _LIBCPP_LIFETIMEBOUND const _MapValueT& __rhs) const {
701 return __comp_(__lhs, __rhs.first);
702 }
703};
704
705template <class _MapValueT, class _Key, class _TransparentKey, class _Compare>
706struct __lazy_synth_three_way_comparator<__map_value_compare<_Key, _MapValueT, _Compare>, _MapValueT, _TransparentKey> {
707 __lazy_synth_three_way_comparator<_Compare, _Key, _TransparentKey> __comp_;
708
709 __lazy_synth_three_way_comparator(
710 _LIBCPP_CTOR_LIFETIMEBOUND const __map_value_compare<_Key, _MapValueT, _Compare>& __comp)
711 : __comp_(__comp.key_comp()) {}
712
713 _LIBCPP_HIDE_FROM_ABI auto
714 operator()(_LIBCPP_LIFETIMEBOUND const _MapValueT& __lhs, _LIBCPP_LIFETIMEBOUND const _TransparentKey& __rhs) const {
715 return __comp_(__lhs.first, __rhs);
716 }
717};
718# endif // _LIBCPP_STD_VER >= 14
719
720template <class _Key, class _CP, class _Compare>
706721inline _LIBCPP_HIDE_FROM_ABI void
707swap(__map_value_compare<_Key, _CP, _Compare, __b>& __x, __map_value_compare<_Key, _CP, _Compare, __b>& __y)
722swap(__map_value_compare<_Key, _CP, _Compare>& __x, __map_value_compare<_Key, _CP, _Compare>& __y)
708723 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
709724 __x.swap(__y);
710725}
......@@ -742,9 +757,9 @@ public:
742757
743758 _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
744759 if (__second_constructed)
745 __alloc_traits::destroy(__na_, std::addressof(__p->__value_.second));
760 __alloc_traits::destroy(__na_, std::addressof(__p->__get_value().second));
746761 if (__first_constructed)
747 __alloc_traits::destroy(__na_, std::addressof(__p->__value_.first));
762 __alloc_traits::destroy(__na_, std::addressof(__p->__get_value().first));
748763 if (__p)
749764 __alloc_traits::deallocate(__na_, __p, 1);
750765 }
......@@ -804,7 +819,26 @@ public:
804819 friend class multimap;
805820 template <class>
806821 friend class __map_const_iterator;
822
823 template <class, class...>
824 friend struct __specialized_algorithm;
825};
826
827# ifndef _LIBCPP_CXX03_LANG
828template <class _Alg, class _TreeIterator>
829struct __specialized_algorithm<_Alg, __iterator_pair<__map_iterator<_TreeIterator>, __map_iterator<_TreeIterator>>> {
830 using __base _LIBCPP_NODEBUG = __specialized_algorithm<_Alg, __iterator_pair<_TreeIterator, _TreeIterator>>;
831
832 static const bool __has_algorithm = __base::__has_algorithm;
833
834 using __iterator _LIBCPP_NODEBUG = __map_iterator<_TreeIterator>;
835
836 template <class... _Args>
837 _LIBCPP_HIDE_FROM_ABI static void operator()(__iterator __first, __iterator __last, _Args&&... __args) {
838 __base()(__first.__i_, __last.__i_, std::forward<_Args>(__args)...);
839 }
807840};
841# endif
808842
809843template <class _TreeIterator>
810844class __map_const_iterator {
......@@ -859,9 +893,33 @@ public:
859893 friend class multimap;
860894 template <class, class, class>
861895 friend class __tree_const_iterator;
896
897 template <class, class...>
898 friend struct __specialized_algorithm;
862899};
863900
864template <class _Key, class _Tp, class _Compare, class _Allocator>
901# ifndef _LIBCPP_CXX03_LANG
902template <class _Alg, class _TreeIterator>
903struct __specialized_algorithm<
904 _Alg,
905 __iterator_pair<__map_const_iterator<_TreeIterator>, __map_const_iterator<_TreeIterator>>> {
906 using __base _LIBCPP_NODEBUG = __specialized_algorithm<_Alg, __iterator_pair<_TreeIterator, _TreeIterator>>;
907
908 static const bool __has_algorithm = __base::__has_algorithm;
909
910 using __iterator _LIBCPP_NODEBUG = __map_const_iterator<_TreeIterator>;
911
912 template <class... _Args>
913 _LIBCPP_HIDE_FROM_ABI static void operator()(__iterator __first, __iterator __last, _Args&&... __args) {
914 __base()(__first.__i_, __last.__i_, std::forward<_Args>(__args)...);
915 }
916};
917# endif
918
919template <class _Key, class _Tp, class _Compare = less<_Key>, class _Allocator = allocator<pair<const _Key, _Tp> > >
920class multimap;
921
922template <class _Key, class _Tp, class _Compare = less<_Key>, class _Allocator = allocator<pair<const _Key, _Tp> > >
865923class map {
866924public:
867925 // types:
......@@ -970,17 +1028,17 @@ public:
9701028 : map(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
9711029# endif
9721030
973 _LIBCPP_HIDE_FROM_ABI map(const map& __m) : __tree_(__m.__tree_) { insert(__m.begin(), __m.end()); }
1031 _LIBCPP_HIDE_FROM_ABI map(const map& __m) = default;
9741032
9751033 _LIBCPP_HIDE_FROM_ABI map& operator=(const map& __m) = default;
9761034
9771035# ifndef _LIBCPP_CXX03_LANG
9781036
979 _LIBCPP_HIDE_FROM_ABI map(map&& __m) noexcept(is_nothrow_move_constructible<__base>::value) = default;
1037 _LIBCPP_HIDE_FROM_ABI map(map&& __m) = default;
9801038
981 _LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a);
1039 _LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a) : __tree_(std::move(__m.__tree_), __a) {}
9821040
983 _LIBCPP_HIDE_FROM_ABI map& operator=(map&& __m) noexcept(is_nothrow_move_assignable<__base>::value) = default;
1041 _LIBCPP_HIDE_FROM_ABI map& operator=(map&& __m) = default;
9841042
9851043 _LIBCPP_HIDE_FROM_ABI map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
9861044 : __tree_(__vc(__comp)) {
......@@ -998,7 +1056,8 @@ public:
9981056# endif
9991057
10001058 _LIBCPP_HIDE_FROM_ABI map& operator=(initializer_list<value_type> __il) {
1001 __tree_.__assign_unique(__il.begin(), __il.end());
1059 clear();
1060 insert(__il.begin(), __il.end());
10021061 return *this;
10031062 }
10041063
......@@ -1006,43 +1065,66 @@ public:
10061065
10071066 _LIBCPP_HIDE_FROM_ABI explicit map(const allocator_type& __a) : __tree_(typename __base::allocator_type(__a)) {}
10081067
1009 _LIBCPP_HIDE_FROM_ABI map(const map& __m, const allocator_type& __a)
1010 : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) {
1011 insert(__m.begin(), __m.end());
1012 }
1068 _LIBCPP_HIDE_FROM_ABI map(const map& __m, const allocator_type& __alloc) : __tree_(__m.__tree_, __alloc) {}
10131069
10141070 _LIBCPP_HIDE_FROM_ABI ~map() { static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
10151071
1016 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
1017 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
1018 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
1019 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
1072 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
1073 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
1074 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
1075 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
10201076
1021 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
1022 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
1023 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
1024 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
1077 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
1078 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
1079 return const_reverse_iterator(end());
1080 }
1081 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
1082 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
1083 return const_reverse_iterator(begin());
1084 }
10251085
1026 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
1027 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
1028 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
1029 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
1086 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
1087 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
1088 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
1089 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
10301090
10311091 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
1032 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
1033 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
1092 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
1093 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
10341094
10351095 _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
10361096# ifndef _LIBCPP_CXX03_LANG
10371097 _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k);
10381098# endif
10391099
1040 _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k);
1041 _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;
1100 template <class _Arg,
1101 __enable_if_t<__is_transparently_comparable_v<_Compare, key_type, __remove_cvref_t<_Arg> >, int> = 0>
1102 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mapped_type& at(_Arg&& __arg) {
1103 auto [_, __child] = __tree_.__find_equal(__arg);
1104 if (__child == nullptr)
1105 std::__throw_out_of_range("map::at: key not found");
1106 return static_cast<__node_pointer>(__child)->__get_value().second;
1107 }
1108
1109 template <class _Arg,
1110 __enable_if_t<__is_transparently_comparable_v<_Compare, key_type, __remove_cvref_t<_Arg> >, int> = 0>
1111 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const mapped_type& at(_Arg&& __arg) const {
1112 auto [_, __child] = __tree_.__find_equal(__arg);
1113 if (__child == nullptr)
1114 std::__throw_out_of_range("map::at: key not found");
1115 return static_cast<__node_pointer>(__child)->__get_value().second;
1116 }
10421117
1043 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return allocator_type(__tree_.__alloc()); }
1044 _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp().key_comp(); }
1045 _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return value_compare(__tree_.value_comp().key_comp()); }
1118 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k);
1119 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;
1120
1121 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
1122 return allocator_type(__tree_.__alloc());
1123 }
1124 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp().key_comp(); }
1125 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const {
1126 return value_compare(__tree_.value_comp().key_comp());
1127 }
10461128
10471129# ifndef _LIBCPP_CXX03_LANG
10481130 template <class... _Args>
......@@ -1052,7 +1134,7 @@ public:
10521134
10531135 template <class... _Args>
10541136 _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {
1055 return __tree_.__emplace_hint_unique(__p.__i_, std::forward<_Args>(__args)...);
1137 return __tree_.__emplace_hint_unique(__p.__i_, std::forward<_Args>(__args)...).first;
10561138 }
10571139
10581140 template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
......@@ -1062,7 +1144,7 @@ public:
10621144
10631145 template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
10641146 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __pos, _Pp&& __p) {
1065 return __tree_.__emplace_hint_unique(__pos.__i_, std::forward<_Pp>(__p));
1147 return __tree_.__emplace_hint_unique(__pos.__i_, std::forward<_Pp>(__p)).first;
10661148 }
10671149
10681150# endif // _LIBCPP_CXX03_LANG
......@@ -1070,7 +1152,7 @@ public:
10701152 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__emplace_unique(__v); }
10711153
10721154 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
1073 return __tree_.__emplace_hint_unique(__p.__i_, __v);
1155 return __tree_.__emplace_hint_unique(__p.__i_, __v).first;
10741156 }
10751157
10761158# ifndef _LIBCPP_CXX03_LANG
......@@ -1079,25 +1161,21 @@ public:
10791161 }
10801162
10811163 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
1082 return __tree_.__emplace_hint_unique(__p.__i_, std::move(__v));
1164 return __tree_.__emplace_hint_unique(__p.__i_, std::move(__v)).first;
10831165 }
10841166
10851167 _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
10861168# endif
10871169
10881170 template <class _InputIterator>
1089 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
1090 for (const_iterator __e = cend(); __f != __l; ++__f)
1091 insert(__e.__i_, *__f);
1171 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last) {
1172 __tree_.__insert_range_unique(__first, __last);
10921173 }
10931174
10941175# if _LIBCPP_STD_VER >= 23
10951176 template <_ContainerCompatibleRange<value_type> _Range>
10961177 _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
1097 const_iterator __end = cend();
1098 for (auto&& __element : __range) {
1099 insert(__end.__i_, std::forward<decltype(__element)>(__element));
1100 }
1178 __tree_.__insert_range_unique(ranges::begin(__range), ranges::end(__range));
11011179 }
11021180# endif
11031181
......@@ -1105,17 +1183,13 @@ public:
11051183
11061184 template <class... _Args>
11071185 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args) {
1108 return __tree_.__emplace_unique_key_args(
1109 __k,
1110 std::piecewise_construct,
1111 std::forward_as_tuple(__k),
1112 std::forward_as_tuple(std::forward<_Args>(__args)...));
1186 return __tree_.__emplace_unique(
1187 std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple(std::forward<_Args>(__args)...));
11131188 }
11141189
11151190 template <class... _Args>
11161191 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args) {
1117 return __tree_.__emplace_unique_key_args(
1118 __k,
1192 return __tree_.__emplace_unique(
11191193 std::piecewise_construct,
11201194 std::forward_as_tuple(std::move(__k)),
11211195 std::forward_as_tuple(std::forward<_Args>(__args)...));
......@@ -1124,9 +1198,8 @@ public:
11241198 template <class... _Args>
11251199 _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) {
11261200 return __tree_
1127 .__emplace_hint_unique_key_args(
1201 .__emplace_hint_unique(
11281202 __h.__i_,
1129 __k,
11301203 std::piecewise_construct,
11311204 std::forward_as_tuple(__k),
11321205 std::forward_as_tuple(std::forward<_Args>(__args)...))
......@@ -1136,9 +1209,8 @@ public:
11361209 template <class... _Args>
11371210 _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) {
11381211 return __tree_
1139 .__emplace_hint_unique_key_args(
1212 .__emplace_hint_unique(
11401213 __h.__i_,
1141 __k,
11421214 std::piecewise_construct,
11431215 std::forward_as_tuple(std::move(__k)),
11441216 std::forward_as_tuple(std::forward<_Args>(__args)...))
......@@ -1147,27 +1219,25 @@ public:
11471219
11481220 template <class _Vp>
11491221 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v) {
1150 iterator __p = lower_bound(__k);
1151 if (__p != end() && !key_comp()(__k, __p->first)) {
1152 __p->second = std::forward<_Vp>(__v);
1153 return std::make_pair(__p, false);
1154 }
1155 return std::make_pair(emplace_hint(__p, __k, std::forward<_Vp>(__v)), true);
1222 auto __result = __tree_.__emplace_unique(__k, std::forward<_Vp>(__v));
1223 auto& [__iter, __inserted] = __result;
1224 if (!__inserted)
1225 __iter->second = std::forward<_Vp>(__v);
1226 return __result;
11561227 }
11571228
11581229 template <class _Vp>
11591230 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v) {
1160 iterator __p = lower_bound(__k);
1161 if (__p != end() && !key_comp()(__k, __p->first)) {
1162 __p->second = std::forward<_Vp>(__v);
1163 return std::make_pair(__p, false);
1164 }
1165 return std::make_pair(emplace_hint(__p, std::move(__k), std::forward<_Vp>(__v)), true);
1231 auto __result = __tree_.__emplace_unique(std::move(__k), std::forward<_Vp>(__v));
1232 auto& [__iter, __inserted] = __result;
1233 if (!__inserted)
1234 __iter->second = std::forward<_Vp>(__v);
1235 return __result;
11661236 }
11671237
11681238 template <class _Vp>
11691239 _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v) {
1170 auto [__r, __inserted] = __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, __k, std::forward<_Vp>(__v));
1240 auto [__r, __inserted] = __tree_.__emplace_hint_unique(__h.__i_, __k, std::forward<_Vp>(__v));
11711241
11721242 if (!__inserted)
11731243 __r->second = std::forward<_Vp>(__v);
......@@ -1177,8 +1247,7 @@ public:
11771247
11781248 template <class _Vp>
11791249 _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __h, key_type&& __k, _Vp&& __v) {
1180 auto [__r, __inserted] =
1181 __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, std::move(__k), std::forward<_Vp>(__v));
1250 auto [__r, __inserted] = __tree_.__emplace_hint_unique(__h.__i_, std::move(__k), std::forward<_Vp>(__v));
11821251
11831252 if (!__inserted)
11841253 __r->second = std::forward<_Vp>(__v);
......@@ -1207,10 +1276,10 @@ public:
12071276 "node_type with incompatible allocator passed to map::insert()");
12081277 return __tree_.template __node_handle_insert_unique<node_type>(__hint.__i_, std::move(__nh));
12091278 }
1210 _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
1279 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
12111280 return __tree_.template __node_handle_extract<node_type>(__key);
12121281 }
1213 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
1282 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
12141283 return __tree_.template __node_handle_extract<node_type>(__it.__i_);
12151284 }
12161285 template <class _Compare2>
......@@ -1241,75 +1310,105 @@ public:
12411310
12421311 _LIBCPP_HIDE_FROM_ABI void swap(map& __m) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) { __tree_.swap(__m.__tree_); }
12431312
1244 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
1245 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
1313 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
1314 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
12461315# if _LIBCPP_STD_VER >= 14
1247 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1248 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1316 template <typename _K2,
1317 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
1318 int> = 0>
1319 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
12491320 return __tree_.find(__k);
12501321 }
1251 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1252 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1322 template <typename _K2,
1323 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
1324 int> = 0>
1325 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
12531326 return __tree_.find(__k);
12541327 }
12551328# endif
12561329
1257 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_unique(__k); }
1330 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const {
1331 return __tree_.__count_unique(__k);
1332 }
12581333# if _LIBCPP_STD_VER >= 14
12591334 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1260 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1335 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
12611336 return __tree_.__count_multi(__k);
12621337 }
12631338# endif
12641339
12651340# if _LIBCPP_STD_VER >= 20
1266 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1267 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1268 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1341 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1342 template <typename _K2,
1343 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
1344 int> = 0>
1345 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
12691346 return find(__k) != end();
12701347 }
12711348# endif // _LIBCPP_STD_VER >= 20
12721349
1273 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.lower_bound(__k); }
1274 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const { return __tree_.lower_bound(__k); }
1350 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) {
1351 return __tree_.__lower_bound_unique(__k);
1352 }
1353
1354 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const {
1355 return __tree_.__lower_bound_unique(__k);
1356 }
1357
1358 // The transparent versions of the lookup functions use the _multi version, since a non-element key is allowed to
1359 // match multiple elements.
12751360# if _LIBCPP_STD_VER >= 14
1276 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1277 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
1278 return __tree_.lower_bound(__k);
1361 template <typename _K2,
1362 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
1363 int> = 0>
1364 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
1365 return __tree_.__lower_bound_multi(__k);
12791366 }
12801367
1281 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1282 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
1283 return __tree_.lower_bound(__k);
1368 template <typename _K2,
1369 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
1370 int> = 0>
1371 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
1372 return __tree_.__lower_bound_multi(__k);
12841373 }
12851374# endif
12861375
1287 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.upper_bound(__k); }
1288 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const { return __tree_.upper_bound(__k); }
1289# if _LIBCPP_STD_VER >= 14
1290 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1291 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
1292 return __tree_.upper_bound(__k);
1376 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) {
1377 return __tree_.__upper_bound_unique(__k);
12931378 }
1294 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1295 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
1296 return __tree_.upper_bound(__k);
1379
1380 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const {
1381 return __tree_.__upper_bound_unique(__k);
1382 }
1383
1384# if _LIBCPP_STD_VER >= 14
1385 template <typename _K2,
1386 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
1387 int> = 0>
1388 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
1389 return __tree_.__upper_bound_multi(__k);
1390 }
1391 template <typename _K2,
1392 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,
1393 int> = 0>
1394 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
1395 return __tree_.__upper_bound_multi(__k);
12971396 }
12981397# endif
12991398
1300 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
1399 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
13011400 return __tree_.__equal_range_unique(__k);
13021401 }
1303 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
1402 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
13041403 return __tree_.__equal_range_unique(__k);
13051404 }
13061405# if _LIBCPP_STD_VER >= 14
13071406 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1308 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
1407 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
13091408 return __tree_.__equal_range_multi(__k);
13101409 }
13111410 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1312 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
1411 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
13131412 return __tree_.__equal_range_multi(__k);
13141413 }
13151414# endif
......@@ -1319,7 +1418,6 @@ private:
13191418 typedef typename __base::__node_allocator __node_allocator;
13201419 typedef typename __base::__node_pointer __node_pointer;
13211420 typedef typename __base::__node_base_pointer __node_base_pointer;
1322 typedef typename __base::__parent_pointer __parent_pointer;
13231421
13241422 typedef __map_node_destructor<__node_allocator> _Dp;
13251423 typedef unique_ptr<__node, _Dp> __node_holder;
......@@ -1327,6 +1425,8 @@ private:
13271425# ifdef _LIBCPP_CXX03_LANG
13281426 _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_with_key(const key_type& __k);
13291427# endif
1428
1429 friend struct __specialized_algorithm<_Algorithm::__for_each, __single_range<map> >;
13301430};
13311431
13321432# if _LIBCPP_STD_VER >= 17
......@@ -1334,8 +1434,8 @@ template <class _InputIterator,
13341434 class _Compare = less<__iter_key_type<_InputIterator>>,
13351435 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
13361436 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1337 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
1338 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1437 class = enable_if_t<!__is_allocator_v<_Compare>>,
1438 class = enable_if_t<__is_allocator_v<_Allocator>>>
13391439map(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
13401440 -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;
13411441
......@@ -1343,8 +1443,8 @@ map(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocat
13431443template <ranges::input_range _Range,
13441444 class _Compare = less<__range_key_type<_Range>>,
13451445 class _Allocator = allocator<__range_to_alloc_type<_Range>>,
1346 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
1347 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1446 class = enable_if_t<!__is_allocator_v<_Compare>>,
1447 class = enable_if_t<__is_allocator_v<_Allocator>>>
13481448map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
13491449 -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;
13501450# endif
......@@ -1353,16 +1453,15 @@ template <class _Key,
13531453 class _Tp,
13541454 class _Compare = less<remove_const_t<_Key>>,
13551455 class _Allocator = allocator<pair<const _Key, _Tp>>,
1356 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
1357 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1358map(initializer_list<pair<_Key, _Tp>>,
1359 _Compare = _Compare(),
1360 _Allocator = _Allocator()) -> map<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
1456 class = enable_if_t<!__is_allocator_v<_Compare>>,
1457 class = enable_if_t<__is_allocator_v<_Allocator>>>
1458map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator())
1459 -> map<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
13611460
13621461template <class _InputIterator,
13631462 class _Allocator,
13641463 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1365 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1464 class = enable_if_t<__is_allocator_v<_Allocator>>>
13661465map(_InputIterator, _InputIterator, _Allocator)
13671466 -> map<__iter_key_type<_InputIterator>,
13681467 __iter_mapped_type<_InputIterator>,
......@@ -1370,44 +1469,44 @@ map(_InputIterator, _InputIterator, _Allocator)
13701469 _Allocator>;
13711470
13721471# if _LIBCPP_STD_VER >= 23
1373template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1472template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
13741473map(from_range_t, _Range&&, _Allocator)
13751474 -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;
13761475# endif
13771476
1378template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1379map(initializer_list<pair<_Key, _Tp>>,
1380 _Allocator) -> map<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;
1477template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
1478map(initializer_list<pair<_Key, _Tp>>, _Allocator)
1479 -> map<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;
13811480# endif
13821481
1383# ifndef _LIBCPP_CXX03_LANG
1482# if _LIBCPP_STD_VER >= 14
13841483template <class _Key, class _Tp, class _Compare, class _Allocator>
1385map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)
1386 : __tree_(std::move(__m.__tree_), typename __base::allocator_type(__a)) {
1387 if (__a != __m.get_allocator()) {
1388 const_iterator __e = cend();
1389 while (!__m.empty()) {
1390 __tree_.__insert_unique_from_orphaned_node(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__value_));
1391 }
1484struct __specialized_algorithm<_Algorithm::__for_each, __single_range<map<_Key, _Tp, _Compare, _Allocator>>> {
1485 using __map _LIBCPP_NODEBUG = map<_Key, _Tp, _Compare, _Allocator>;
1486
1487 static const bool __has_algorithm = true;
1488
1489 template <class _Map, class _Func, class _Proj>
1490 _LIBCPP_HIDE_FROM_ABI static auto operator()(_Map&& __map, _Func __func, _Proj __proj) {
1491 auto [_, __func2] = __specialized_algorithm<_Algorithm::__for_each, __single_range<typename __map::__base>>()(
1492 __map.__tree_, std::move(__func), std::move(__proj));
1493 return std::make_pair(__map.end(), std::move(__func2));
13921494 }
1393}
1495};
1496# endif
13941497
1498# ifndef _LIBCPP_CXX03_LANG
13951499template <class _Key, class _Tp, class _Compare, class _Allocator>
13961500_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) {
1397 return __tree_
1398 .__emplace_unique_key_args(__k, std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple())
1501 return __tree_.__emplace_unique(std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple())
13991502 .first->second;
14001503}
14011504
14021505template <class _Key, class _Tp, class _Compare, class _Allocator>
14031506_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k) {
1404 // TODO investigate this clang-tidy warning.
1405 // NOLINTBEGIN(bugprone-use-after-move)
14061507 return __tree_
1407 .__emplace_unique_key_args(
1408 __k, std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple())
1508 .__emplace_unique(std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple())
14091509 .first->second;
1410 // NOLINTEND(bugprone-use-after-move)
14111510}
14121511
14131512# else // _LIBCPP_CXX03_LANG
......@@ -1417,44 +1516,41 @@ typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
14171516map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k) {
14181517 __node_allocator& __na = __tree_.__node_alloc();
14191518 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1420 __node_traits::construct(__na, std::addressof(__h->__value_.first), __k);
1519 __node_traits::construct(__na, std::addressof(__h->__get_value().first), __k);
14211520 __h.get_deleter().__first_constructed = true;
1422 __node_traits::construct(__na, std::addressof(__h->__value_.second));
1521 __node_traits::construct(__na, std::addressof(__h->__get_value().second));
14231522 __h.get_deleter().__second_constructed = true;
14241523 return __h;
14251524}
14261525
14271526template <class _Key, class _Tp, class _Compare, class _Allocator>
14281527_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) {
1429 __parent_pointer __parent;
1430 __node_base_pointer& __child = __tree_.__find_equal(__parent, __k);
1431 __node_pointer __r = static_cast<__node_pointer>(__child);
1528 auto [__parent, __child] = __tree_.__find_equal(__k);
1529 __node_pointer __r = static_cast<__node_pointer>(__child);
14321530 if (__child == nullptr) {
14331531 __node_holder __h = __construct_node_with_key(__k);
14341532 __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
14351533 __r = __h.release();
14361534 }
1437 return __r->__value_.second;
1535 return __r->__get_value().second;
14381536}
14391537
14401538# endif // _LIBCPP_CXX03_LANG
14411539
14421540template <class _Key, class _Tp, class _Compare, class _Allocator>
14431541_Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) {
1444 __parent_pointer __parent;
1445 __node_base_pointer& __child = __tree_.__find_equal(__parent, __k);
1542 auto [_, __child] = __tree_.__find_equal(__k);
14461543 if (__child == nullptr)
14471544 std::__throw_out_of_range("map::at: key not found");
1448 return static_cast<__node_pointer>(__child)->__value_.second;
1545 return static_cast<__node_pointer>(__child)->__get_value().second;
14491546}
14501547
14511548template <class _Key, class _Tp, class _Compare, class _Allocator>
14521549const _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const {
1453 __parent_pointer __parent;
1454 __node_base_pointer __child = __tree_.__find_equal(__parent, __k);
1550 auto [_, __child] = __tree_.__find_equal(__k);
14551551 if (__child == nullptr)
14561552 std::__throw_out_of_range("map::at: key not found");
1457 return static_cast<__node_pointer>(__child)->__value_.second;
1553 return static_cast<__node_pointer>(__child)->__get_value().second;
14581554}
14591555
14601556template <class _Key, class _Tp, class _Compare, class _Allocator>
......@@ -1637,22 +1733,17 @@ public:
16371733 : multimap(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
16381734# endif
16391735
1640 _LIBCPP_HIDE_FROM_ABI multimap(const multimap& __m)
1641 : __tree_(__m.__tree_.value_comp(),
1642 __alloc_traits::select_on_container_copy_construction(__m.__tree_.__alloc())) {
1643 insert(__m.begin(), __m.end());
1644 }
1736 _LIBCPP_HIDE_FROM_ABI multimap(const multimap& __m) = default;
16451737
16461738 _LIBCPP_HIDE_FROM_ABI multimap& operator=(const multimap& __m) = default;
16471739
16481740# ifndef _LIBCPP_CXX03_LANG
16491741
1650 _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m) noexcept(is_nothrow_move_constructible<__base>::value) = default;
1742 _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m) = default;
16511743
1652 _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a);
1744 _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a) : __tree_(std::move(__m.__tree_), __a) {}
16531745
1654 _LIBCPP_HIDE_FROM_ABI multimap&
1655 operator=(multimap&& __m) noexcept(is_nothrow_move_assignable<__base>::value) = default;
1746 _LIBCPP_HIDE_FROM_ABI multimap& operator=(multimap&& __m) = default;
16561747
16571748 _LIBCPP_HIDE_FROM_ABI multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
16581749 : __tree_(__vc(__comp)) {
......@@ -1671,7 +1762,8 @@ public:
16711762# endif
16721763
16731764 _LIBCPP_HIDE_FROM_ABI multimap& operator=(initializer_list<value_type> __il) {
1674 __tree_.__assign_multi(__il.begin(), __il.end());
1765 clear();
1766 insert(__il.begin(), __il.end());
16751767 return *this;
16761768 }
16771769
......@@ -1679,37 +1771,42 @@ public:
16791771
16801772 _LIBCPP_HIDE_FROM_ABI explicit multimap(const allocator_type& __a) : __tree_(typename __base::allocator_type(__a)) {}
16811773
1682 _LIBCPP_HIDE_FROM_ABI multimap(const multimap& __m, const allocator_type& __a)
1683 : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) {
1684 insert(__m.begin(), __m.end());
1685 }
1774 _LIBCPP_HIDE_FROM_ABI multimap(const multimap& __m, const allocator_type& __a) : __tree_(__m.__tree_, __a) {}
16861775
16871776 _LIBCPP_HIDE_FROM_ABI ~multimap() {
16881777 static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), "");
16891778 }
16901779
1691 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
1692 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
1693 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
1694 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
1780 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
1781 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
1782 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
1783 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
16951784
1696 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
1697 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
1698 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
1699 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
1785 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
1786 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
1787 return const_reverse_iterator(end());
1788 }
1789 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
1790 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
1791 return const_reverse_iterator(begin());
1792 }
17001793
1701 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
1702 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
1703 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
1704 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
1794 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
1795 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
1796 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
1797 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
17051798
17061799 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
1707 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
1708 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
1800 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
1801 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
17091802
1710 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return allocator_type(__tree_.__alloc()); }
1711 _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp().key_comp(); }
1712 _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return value_compare(__tree_.value_comp().key_comp()); }
1803 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
1804 return allocator_type(__tree_.__alloc());
1805 }
1806 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp().key_comp(); }
1807 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const {
1808 return value_compare(__tree_.value_comp().key_comp());
1809 }
17131810
17141811# ifndef _LIBCPP_CXX03_LANG
17151812
......@@ -1751,17 +1848,13 @@ public:
17511848
17521849 template <class _InputIterator>
17531850 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
1754 for (const_iterator __e = cend(); __f != __l; ++__f)
1755 __tree_.__emplace_hint_multi(__e.__i_, *__f);
1851 __tree_.__insert_range_multi(__f, __l);
17561852 }
17571853
17581854# if _LIBCPP_STD_VER >= 23
17591855 template <_ContainerCompatibleRange<value_type> _Range>
17601856 _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
1761 const_iterator __end = cend();
1762 for (auto&& __element : __range) {
1763 __tree_.__emplace_hint_multi(__end.__i_, std::forward<decltype(__element)>(__element));
1764 }
1857 __tree_.__insert_range_multi(ranges::begin(__range), ranges::end(__range));
17651858 }
17661859# endif
17671860
......@@ -1783,10 +1876,10 @@ public:
17831876 "node_type with incompatible allocator passed to multimap::insert()");
17841877 return __tree_.template __node_handle_insert_multi<node_type>(__hint.__i_, std::move(__nh));
17851878 }
1786 _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
1879 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
17871880 return __tree_.template __node_handle_extract<node_type>(__key);
17881881 }
1789 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
1882 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
17901883 return __tree_.template __node_handle_extract<node_type>(__it.__i_);
17911884 }
17921885 template <class _Compare2>
......@@ -1821,75 +1914,89 @@ public:
18211914 __tree_.swap(__m.__tree_);
18221915 }
18231916
1824 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
1825 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
1917 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
1918 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
18261919# if _LIBCPP_STD_VER >= 14
18271920 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1828 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1921 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
18291922 return __tree_.find(__k);
18301923 }
18311924 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1832 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1925 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
18331926 return __tree_.find(__k);
18341927 }
18351928# endif
18361929
1837 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_multi(__k); }
1930 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const {
1931 return __tree_.__count_multi(__k);
1932 }
18381933# if _LIBCPP_STD_VER >= 14
18391934 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1840 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1935 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
18411936 return __tree_.__count_multi(__k);
18421937 }
18431938# endif
18441939
18451940# if _LIBCPP_STD_VER >= 20
1846 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1941 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
18471942 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1848 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1943 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
18491944 return find(__k) != end();
18501945 }
18511946# endif // _LIBCPP_STD_VER >= 20
18521947
1853 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.lower_bound(__k); }
1854 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const { return __tree_.lower_bound(__k); }
1948 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) {
1949 return __tree_.__lower_bound_multi(__k);
1950 }
1951
1952 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const {
1953 return __tree_.__lower_bound_multi(__k);
1954 }
1955
18551956# if _LIBCPP_STD_VER >= 14
18561957 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1857 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
1858 return __tree_.lower_bound(__k);
1958 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
1959 return __tree_.__lower_bound_multi(__k);
18591960 }
18601961
18611962 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1862 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
1863 return __tree_.lower_bound(__k);
1963 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
1964 return __tree_.__lower_bound_multi(__k);
18641965 }
18651966# endif
18661967
1867 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.upper_bound(__k); }
1868 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const { return __tree_.upper_bound(__k); }
1968 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) {
1969 return __tree_.__upper_bound_multi(__k);
1970 }
1971
1972 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const {
1973 return __tree_.__upper_bound_multi(__k);
1974 }
1975
18691976# if _LIBCPP_STD_VER >= 14
18701977 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1871 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
1872 return __tree_.upper_bound(__k);
1978 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
1979 return __tree_.__upper_bound_multi(__k);
18731980 }
18741981 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1875 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
1876 return __tree_.upper_bound(__k);
1982 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
1983 return __tree_.__upper_bound_multi(__k);
18771984 }
18781985# endif
18791986
1880 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
1987 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
18811988 return __tree_.__equal_range_multi(__k);
18821989 }
1883 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
1990 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
18841991 return __tree_.__equal_range_multi(__k);
18851992 }
18861993# if _LIBCPP_STD_VER >= 14
18871994 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1888 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
1995 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
18891996 return __tree_.__equal_range_multi(__k);
18901997 }
18911998 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1892 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
1999 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
18932000 return __tree_.__equal_range_multi(__k);
18942001 }
18952002# endif
......@@ -1901,6 +2008,8 @@ private:
19012008
19022009 typedef __map_node_destructor<__node_allocator> _Dp;
19032010 typedef unique_ptr<__node, _Dp> __node_holder;
2011
2012 friend struct __specialized_algorithm<_Algorithm::__for_each, __single_range<multimap> >;
19042013};
19052014
19062015# if _LIBCPP_STD_VER >= 17
......@@ -1908,8 +2017,8 @@ template <class _InputIterator,
19082017 class _Compare = less<__iter_key_type<_InputIterator>>,
19092018 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
19102019 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1911 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
1912 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2020 class = enable_if_t<!__is_allocator_v<_Compare>>,
2021 class = enable_if_t<__is_allocator_v<_Allocator>>>
19132022multimap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
19142023 -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;
19152024
......@@ -1917,8 +2026,8 @@ multimap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Al
19172026template <ranges::input_range _Range,
19182027 class _Compare = less<__range_key_type<_Range>>,
19192028 class _Allocator = allocator<__range_to_alloc_type<_Range>>,
1920 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
1921 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2029 class = enable_if_t<!__is_allocator_v<_Compare>>,
2030 class = enable_if_t<__is_allocator_v<_Allocator>>>
19222031multimap(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
19232032 -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;
19242033# endif
......@@ -1927,16 +2036,15 @@ template <class _Key,
19272036 class _Tp,
19282037 class _Compare = less<remove_const_t<_Key>>,
19292038 class _Allocator = allocator<pair<const _Key, _Tp>>,
1930 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
1931 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1932multimap(initializer_list<pair<_Key, _Tp>>,
1933 _Compare = _Compare(),
1934 _Allocator = _Allocator()) -> multimap<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
2039 class = enable_if_t<!__is_allocator_v<_Compare>>,
2040 class = enable_if_t<__is_allocator_v<_Allocator>>>
2041multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator())
2042 -> multimap<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
19352043
19362044template <class _InputIterator,
19372045 class _Allocator,
19382046 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1939 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2047 class = enable_if_t<__is_allocator_v<_Allocator>>>
19402048multimap(_InputIterator, _InputIterator, _Allocator)
19412049 -> multimap<__iter_key_type<_InputIterator>,
19422050 __iter_mapped_type<_InputIterator>,
......@@ -1944,26 +2052,30 @@ multimap(_InputIterator, _InputIterator, _Allocator)
19442052 _Allocator>;
19452053
19462054# if _LIBCPP_STD_VER >= 23
1947template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2055template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
19482056multimap(from_range_t, _Range&&, _Allocator)
19492057 -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;
19502058# endif
19512059
1952template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1953multimap(initializer_list<pair<_Key, _Tp>>,
1954 _Allocator) -> multimap<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;
2060template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
2061multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
2062 -> multimap<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;
19552063# endif
19562064
1957# ifndef _LIBCPP_CXX03_LANG
2065# if _LIBCPP_STD_VER >= 14
19582066template <class _Key, class _Tp, class _Compare, class _Allocator>
1959multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a)
1960 : __tree_(std::move(__m.__tree_), typename __base::allocator_type(__a)) {
1961 if (__a != __m.get_allocator()) {
1962 const_iterator __e = cend();
1963 while (!__m.empty())
1964 __tree_.__insert_multi_from_orphaned_node(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__value_));
2067struct __specialized_algorithm<_Algorithm::__for_each, __single_range<multimap<_Key, _Tp, _Compare, _Allocator>>> {
2068 using __map _LIBCPP_NODEBUG = multimap<_Key, _Tp, _Compare, _Allocator>;
2069
2070 static const bool __has_algorithm = true;
2071
2072 template <class _Map, class _Func, class _Proj>
2073 _LIBCPP_HIDE_FROM_ABI static auto operator()(_Map&& __map, _Func __func, _Proj __proj) {
2074 auto [_, __func2] = __specialized_algorithm<_Algorithm::__for_each, __single_range<typename __map::__base>>()(
2075 __map.__tree_, std::move(__func), std::move(__proj));
2076 return std::make_pair(__map.end(), std::move(__func2));
19652077 }
1966}
2078};
19672079# endif
19682080
19692081template <class _Key, class _Tp, class _Compare, class _Allocator>
lib/libcxx/include/math.h+19
......@@ -429,6 +429,25 @@ using std::__math::isnormal;
429429using std::__math::isunordered;
430430# endif // _LIBCPP_MSVCRT
431431
432# if defined(_LIBCPP_MSVCRT) && _LIBCPP_STD_VER >= 20
433// MS UCRT incorrectly defines some functions in a way not working with integer types. Until C++20, this was worked
434// around by -fdelayed-template-parsing. Since C++20, we can use standard feature "requires" instead.
435
436// TODO: Remove the workaround once UCRT fixes these functions. Note that this doesn't seem planned as of 2025-07 per
437// https://developercommunity.visualstudio.com/t/10294165.
438
439using std::__math::__ucrt::isfinite;
440using std::__math::__ucrt::isgreater;
441using std::__math::__ucrt::isgreaterequal;
442using std::__math::__ucrt::isinf;
443using std::__math::__ucrt::isless;
444using std::__math::__ucrt::islessequal;
445using std::__math::__ucrt::islessgreater;
446using std::__math::__ucrt::isnan;
447using std::__math::__ucrt::isnormal;
448using std::__math::__ucrt::isunordered;
449# endif // defined(_LIBCPP_MSVCRT) && _LIBCPP_STD_VER >= 20
450
432451// We have to provide double overloads for <math.h> to work on platforms that don't provide the full set of math
433452// functions. To make the overload set work with multiple functions that take the same arguments, we make our overloads
434453// templates. Functions are preferred over function templates during overload resolution, which means that our overload
lib/libcxx/include/mdspan+1-5
......@@ -450,11 +450,7 @@ namespace std {
450450# include <__config>
451451
452452# if _LIBCPP_STD_VER >= 23
453# include <__fwd/mdspan.h> // TODO(boomanaiden154): This is currently a
454 // non-standard extension to include
455 // std::dynamic_extent tracked by LWG issue 4275.
456 // This comment should be deleted or the include
457 // deleted upon resolution.
453# include <__fwd/mdspan.h>
458454# include <__fwd/span.h>
459455# include <__mdspan/default_accessor.h>
460456# include <__mdspan/extents.h>
lib/libcxx/include/mutex+29-19
......@@ -229,12 +229,12 @@ public:
229229 recursive_mutex& operator=(const recursive_mutex&) = delete;
230230
231231 void lock();
232 bool try_lock() _NOEXCEPT;
232 [[__nodiscard__]] bool try_lock() _NOEXCEPT;
233233 void unlock() _NOEXCEPT;
234234
235235 typedef __libcpp_recursive_mutex_t* native_handle_type;
236236
237 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
237 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
238238};
239239
240240class _LIBCPP_EXPORTED_FROM_ABI timed_mutex {
......@@ -251,14 +251,14 @@ public:
251251
252252public:
253253 void lock();
254 bool try_lock() _NOEXCEPT;
254 [[__nodiscard__]] bool try_lock() _NOEXCEPT;
255255 template <class _Rep, class _Period>
256 _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
256 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
257257 return try_lock_until(chrono::steady_clock::now() + __d);
258258 }
259259
260260 template <class _Clock, class _Duration>
261 _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
261 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
262262 using namespace chrono;
263263 unique_lock<mutex> __lk(__m_);
264264 bool __no_timeout = _Clock::now() < __t;
......@@ -288,14 +288,14 @@ public:
288288 recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
289289
290290 void lock();
291 bool try_lock() _NOEXCEPT;
291 [[__nodiscard__]] bool try_lock() _NOEXCEPT;
292292 template <class _Rep, class _Period>
293 _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
293 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
294294 return try_lock_until(chrono::steady_clock::now() + __d);
295295 }
296296
297297 template <class _Clock, class _Duration>
298 _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
298 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
299299 using namespace chrono;
300300 __thread_id __id = this_thread::get_id();
301301 unique_lock<mutex> __lk(__m_);
......@@ -320,7 +320,7 @@ public:
320320};
321321
322322template <class _L0, class _L1>
323_LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
323[[__nodiscard__]] _LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
324324 unique_lock<_L0> __u0(__l0, try_to_lock_t());
325325 if (__u0.owns_lock()) {
326326 if (__l1.try_lock()) {
......@@ -335,7 +335,8 @@ _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
335335# ifndef _LIBCPP_CXX03_LANG
336336
337337template <class _L0, class _L1, class _L2, class... _L3>
338_LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
338[[__nodiscard__]] _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
339 _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
339340 int __r = 0;
340341 unique_lock<_L0> __u0(__l0, try_to_lock);
341342 if (__u0.owns_lock()) {
......@@ -350,8 +351,11 @@ _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3
350351
351352# endif // _LIBCPP_CXX03_LANG
352353
354// We're using unique_lock to implement the functions, which thread annotations don't support. So we have to disable
355// the analysis inside the function.
353356template <class _L0, class _L1>
354_LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1) {
357_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1)
358 _LIBCPP_ACQUIRE_CAPABILITY(__l0, __l1) {
355359 while (true) {
356360 {
357361 unique_lock<_L0> __u0(__l0);
......@@ -375,7 +379,7 @@ _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1) {
375379# ifndef _LIBCPP_CXX03_LANG
376380
377381template <class _L0, class _L1, class _L2, class... _L3>
378void __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
382_LIBCPP_NO_THREAD_SAFETY_ANALYSIS void __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
379383 while (true) {
380384 switch (__i) {
381385 case 0: {
......@@ -410,8 +414,14 @@ void __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
410414 }
411415}
412416
417// We're using unique_lock to implement the functions, which thread annotations don't support. So we have to disable
418// the analysis inside the function.
413419template <class _L0, class _L1, class _L2, class... _L3>
414inline _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
420_LIBCPP_NO_THREAD_SAFETY_ANALYSIS inline _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3)
421# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 2101
422 _LIBCPP_ACQUIRE_CAPABILITY(__l0, __l1, __l2, __l3...)
423# endif
424{
415425 std::__lock_first(0, __l0, __l1, __l2, __l3...);
416426}
417427
......@@ -469,17 +479,14 @@ public:
469479
470480 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI scoped_lock(adopt_lock_t, _MArgs&... __margs) : __t_(__margs...) {}
471481
472 _LIBCPP_HIDE_FROM_ABI ~scoped_lock() {
473 typedef typename __make_tuple_indices<sizeof...(_MArgs)>::type _Indices;
474 __unlock_unpack(_Indices{}, __t_);
475 }
482 _LIBCPP_HIDE_FROM_ABI ~scoped_lock() { __unlock_unpack(make_index_sequence<sizeof...(_MArgs)>(), __t_); }
476483
477484 scoped_lock(scoped_lock const&) = delete;
478485 scoped_lock& operator=(scoped_lock const&) = delete;
479486
480487private:
481488 template <size_t... _Indx>
482 _LIBCPP_HIDE_FROM_ABI static void __unlock_unpack(__tuple_indices<_Indx...>, _MutexTuple& __mt) {
489 _LIBCPP_HIDE_FROM_ABI static void __unlock_unpack(index_sequence<_Indx...>, _MutexTuple& __mt) {
483490 (std::get<_Indx>(__mt).unlock(), ...);
484491 }
485492
......@@ -494,6 +501,10 @@ _LIBCPP_END_NAMESPACE_STD
494501
495502_LIBCPP_POP_MACROS
496503
504# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23
505# include <typeinfo>
506# endif
507
497508# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
498509# include <atomic>
499510# include <concepts>
......@@ -507,7 +518,6 @@ _LIBCPP_POP_MACROS
507518# include <stdexcept>
508519# include <system_error>
509520# include <type_traits>
510# include <typeinfo>
511521# endif
512522#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
513523
lib/libcxx/include/optional+644-149
......@@ -20,6 +20,11 @@ namespace std {
2020 template <class T>
2121 class optional;
2222
23 template<class T>
24 constexpr bool ranges::enable_view<optional<T>> = true;
25 template<class T>
26 constexpr auto format_kind<optional<T>> = range_format::disabled;
27
2328 template<class T>
2429 concept is-derived-from-optional = requires(const T& t) { // exposition only
2530 []<class U>(const optional<U>&){ }(t);
......@@ -102,6 +107,8 @@ namespace std {
102107 class optional {
103108 public:
104109 using value_type = T;
110 using iterator = implementation-defined; // see [optional.iterators]
111 using const_iterator = implementation-defined; // see [optional.iterators]
105112
106113 // [optional.ctor], constructors
107114 constexpr optional() noexcept;
......@@ -112,7 +119,7 @@ namespace std {
112119 constexpr explicit optional(in_place_t, Args &&...);
113120 template<class U, class... Args>
114121 constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
115 template<class U = T>
122 template<class U = remove_cv_t<T>>
116123 constexpr explicit(see-below) optional(U &&);
117124 template<class U>
118125 explicit(see-below) optional(const optional<U> &); // constexpr in C++20
......@@ -126,7 +133,7 @@ namespace std {
126133 optional &operator=(nullopt_t) noexcept; // constexpr in C++20
127134 constexpr optional &operator=(const optional &);
128135 constexpr optional &operator=(optional &&) noexcept(see below);
129 template<class U = T> optional &operator=(U &&); // constexpr in C++20
136 template<class U = remove_cv_t<T>> optional &operator=(U &&); // constexpr in C++20
130137 template<class U> optional &operator=(const optional<U> &); // constexpr in C++20
131138 template<class U> optional &operator=(optional<U> &&); // constexpr in C++20
132139 template<class... Args> T& emplace(Args &&...); // constexpr in C++20
......@@ -135,6 +142,12 @@ namespace std {
135142 // [optional.swap], swap
136143 void swap(optional &) noexcept(see below ); // constexpr in C++20
137144
145 // [optional.iterators], iterator support
146 constexpr iterator begin() noexcept;
147 constexpr const_iterator begin() const noexcept;
148 constexpr iterator end() noexcept;
149 constexpr const_iterator end() const noexcept;
150
138151 // [optional.observe], observers
139152 constexpr T const *operator->() const noexcept;
140153 constexpr T *operator->() noexcept;
......@@ -148,8 +161,8 @@ namespace std {
148161 constexpr T &value() &;
149162 constexpr T &&value() &&;
150163 constexpr const T &&value() const &&;
151 template<class U> constexpr T value_or(U &&) const &;
152 template<class U> constexpr T value_or(U &&) &&;
164 template<class U = remove_cv_t<T>> constexpr T value_or(U &&) const &;
165 template<class U = remove_cv_t<T>> constexpr T value_or(U &&) &&;
153166
154167 // [optional.monadic], monadic operations
155168 template<class F> constexpr auto and_then(F&& f) &; // since C++23
......@@ -173,6 +186,71 @@ namespace std {
173186 template<class T>
174187 optional(T) -> optional<T>;
175188
189 template<class T>
190 class optional<T&> { // since C++26
191 public:
192 using value_type = T;
193 using iterator = implementation-defined; // see [optional.ref.iterators]
194
195 public:
196 // [optional.ref.ctor], constructors
197 constexpr optional() noexcept = default;
198 constexpr optional(nullopt_t) noexcept : optional() {}
199 constexpr optional(const optional& rhs) noexcept = default;
200
201 template<class Arg>
202 constexpr explicit optional(in_place_t, Arg&& arg);
203 template<class U>
204 constexpr explicit(see below) optional(U&& u) noexcept(see below);
205 template<class U>
206 constexpr explicit(see below) optional(optional<U>& rhs) noexcept(see below);
207 template<class U>
208 constexpr explicit(see below) optional(const optional<U>& rhs) noexcept(see below);
209 template<class U>
210 constexpr explicit(see below) optional(optional<U>&& rhs) noexcept(see below);
211 template<class U>
212 constexpr explicit(see below) optional(const optional<U>&& rhs) noexcept(see below);
213
214 constexpr ~optional() = default;
215
216 // [optional.ref.assign], assignment
217 constexpr optional& operator=(nullopt_t) noexcept;
218 constexpr optional& operator=(const optional& rhs) noexcept = default;
219
220 template<class U> constexpr T& emplace(U&& u) noexcept(see below);
221
222 // [optional.ref.swap], swap
223 constexpr void swap(optional& rhs) noexcept;
224
225 // [optional.ref.iterators], iterator support
226 constexpr iterator begin() const noexcept;
227 constexpr iterator end() const noexcept;
228
229 // [optional.ref.observe], observers
230 constexpr T* operator->() const noexcept;
231 constexpr T& operator*() const noexcept;
232 constexpr explicit operator bool() const noexcept;
233 constexpr bool has_value() const noexcept;
234 constexpr T& value() const; // freestanding-deleted
235 template<class U = remove_cv_t<T>>
236 constexpr remove_cv_t<T> value_or(U&& u) const;
237
238 // [optional.ref.monadic], monadic operations
239 template<class F> constexpr auto and_then(F&& f) const;
240 template<class F> constexpr optional<invoke_result_t<F, T&>> transform(F&& f) const;
241 template<class F> constexpr optional or_else(F&& f) const;
242
243 // [optional.ref.mod], modifiers
244 constexpr void reset() noexcept;
245
246 private:
247 T* val = nullptr; // exposition only
248
249 // [optional.ref.expos], exposition only helper functions
250 template<class U>
251 constexpr void convert-ref-init-val(U&& u); // exposition only
252 };
253
176254} // namespace std
177255
178256*/
......@@ -186,13 +264,19 @@ namespace std {
186264# include <__compare/three_way_comparable.h>
187265# include <__concepts/invocable.h>
188266# include <__config>
267# include <__cstddef/ptrdiff_t.h>
189268# include <__exception/exception.h>
269# include <__format/range_format.h>
190270# include <__functional/hash.h>
191271# include <__functional/invoke.h>
192272# include <__functional/unary_function.h>
193273# include <__fwd/functional.h>
274# include <__iterator/bounded_iter.h>
275# include <__iterator/wrap_iter.h>
194276# include <__memory/addressof.h>
195277# include <__memory/construct_at.h>
278# include <__ranges/enable_borrowed_range.h>
279# include <__ranges/enable_view.h>
196280# include <__tuple/sfinae_helpers.h>
197281# include <__type_traits/add_pointer.h>
198282# include <__type_traits/conditional.h>
......@@ -200,6 +284,7 @@ namespace std {
200284# include <__type_traits/decay.h>
201285# include <__type_traits/disjunction.h>
202286# include <__type_traits/enable_if.h>
287# include <__type_traits/integral_constant.h>
203288# include <__type_traits/invoke.h>
204289# include <__type_traits/is_array.h>
205290# include <__type_traits/is_assignable.h>
......@@ -207,11 +292,11 @@ namespace std {
207292# include <__type_traits/is_convertible.h>
208293# include <__type_traits/is_core_convertible.h>
209294# include <__type_traits/is_destructible.h>
295# include <__type_traits/is_function.h>
210296# include <__type_traits/is_nothrow_assignable.h>
211297# include <__type_traits/is_nothrow_constructible.h>
212298# include <__type_traits/is_object.h>
213299# include <__type_traits/is_reference.h>
214# include <__type_traits/is_replaceable.h>
215300# include <__type_traits/is_same.h>
216301# include <__type_traits/is_scalar.h>
217302# include <__type_traits/is_swappable.h>
......@@ -220,6 +305,7 @@ namespace std {
220305# include <__type_traits/is_trivially_destructible.h>
221306# include <__type_traits/is_trivially_relocatable.h>
222307# include <__type_traits/negation.h>
308# include <__type_traits/reference_constructs_from_temporary.h>
223309# include <__type_traits/remove_const.h>
224310# include <__type_traits/remove_cv.h>
225311# include <__type_traits/remove_cvref.h>
......@@ -255,7 +341,7 @@ public:
255341 _LIBCPP_HIDE_FROM_ABI bad_optional_access& operator=(const bad_optional_access&) _NOEXCEPT = default;
256342 // Get the key function ~bad_optional_access() into the dylib
257343 ~bad_optional_access() _NOEXCEPT override;
258 const char* what() const _NOEXCEPT override;
344 [[__nodiscard__]] const char* what() const _NOEXCEPT override;
259345};
260346
261347} // namespace std
......@@ -358,7 +444,7 @@ struct __optional_storage_base : __optional_destruct_base<_Tp> {
358444 using value_type = _Tp;
359445 using __base::__base;
360446
361 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__engaged_; }
447 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__engaged_; }
362448
363449 _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() & noexcept { return this->__val_; }
364450 _LIBCPP_HIDE_FROM_ABI constexpr const value_type& __get() const& noexcept { return this->__val_; }
......@@ -390,58 +476,60 @@ struct __optional_storage_base : __optional_destruct_base<_Tp> {
390476 __construct(std::forward<_That>(__opt).__get());
391477 }
392478 }
479
480 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
481 __swap(__optional_storage_base& __rhs) noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp>) {
482 using std::swap;
483 if (this->has_value() == __rhs.has_value()) {
484 if (this->has_value())
485 swap(this->__get(), __rhs.__get());
486 } else {
487 if (this->has_value()) {
488 __rhs.__construct(std::move(this->__get()));
489 this->reset();
490 } else {
491 this->__construct(std::move(__rhs.__get()));
492 __rhs.reset();
493 }
494 }
495 }
393496};
394497
395// optional<T&> is currently required to be ill-formed. However, it may
396// be allowed in the future. For this reason, it has already been implemented
397// to ensure we can make the change in an ABI-compatible manner.
398498template <class _Tp>
399499struct __optional_storage_base<_Tp, true> {
400500 using value_type = _Tp;
401501 using __raw_type _LIBCPP_NODEBUG = remove_reference_t<_Tp>;
402502 __raw_type* __value_;
403503
504 _LIBCPP_HIDE_FROM_ABI constexpr __optional_storage_base() noexcept : __value_(nullptr) {}
505
404506 template <class _Up>
405 static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
406 using _RawUp = __libcpp_remove_reference_t<_Up>;
407 using _UpPtr = _RawUp*;
408 using _RawTp = __libcpp_remove_reference_t<_Tp>;
409 using _TpPtr = _RawTp*;
410 using _CheckLValueArg =
411 integral_constant<bool,
412 (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value) ||
413 is_same<_RawUp, reference_wrapper<_RawTp>>::value ||
414 is_same<_RawUp, reference_wrapper<__remove_const_t<_RawTp>>>::value >;
415 return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value) ||
416 (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
417 is_convertible<_UpPtr, _TpPtr>::value);
507 _LIBCPP_HIDE_FROM_ABI constexpr void __convert_init_ref_val(_Up&& __val) noexcept {
508 _Tp& __r(std::forward<_Up>(__val));
509 __value_ = std::addressof(__r);
418510 }
419511
420 _LIBCPP_HIDE_FROM_ABI constexpr __optional_storage_base() noexcept : __value_(nullptr) {}
421
422512 template <class _UArg>
423 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
424 : __value_(std::addressof(__uarg)) {
425 static_assert(__can_bind_reference<_UArg>(),
426 "Attempted to construct a reference element in tuple from a "
513 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg) {
514 static_assert(!__reference_constructs_from_temporary_v<_Tp, _UArg>,
515 "Attempted to construct a reference element in optional from a "
427516 "possible temporary");
517 __convert_init_ref_val(std::forward<_UArg>(__uarg));
428518 }
429519
430520 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { __value_ = nullptr; }
431521
432 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __value_ != nullptr; }
433
434 _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() const& noexcept { return *__value_; }
522 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __value_ != nullptr; }
435523
436 _LIBCPP_HIDE_FROM_ABI constexpr value_type&& __get() const&& noexcept { return std::forward<value_type>(*__value_); }
524 _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() const noexcept { return *__value_; }
437525
438526 template <class _UArg>
439527 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val) {
440528 _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
441 static_assert(__can_bind_reference<_UArg>(),
529 static_assert(!__reference_constructs_from_temporary_v<_Tp, _UArg>,
442530 "Attempted to construct a reference element in tuple from a "
443531 "possible temporary");
444 __value_ = std::addressof(__val);
532 __convert_init_ref_val(std::forward<_UArg>(__val));
445533 }
446534
447535 template <class _That>
......@@ -462,9 +550,13 @@ struct __optional_storage_base<_Tp, true> {
462550 __construct(std::forward<_That>(__opt).__get());
463551 }
464552 }
553
554 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __swap(__optional_storage_base& __rhs) noexcept {
555 std::swap(__value_, __rhs.__value_);
556 }
465557};
466558
467template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
559template <class _Tp, bool = is_trivially_copy_constructible_v<_Tp> || is_lvalue_reference_v<_Tp>>
468560struct __optional_copy_base : __optional_storage_base<_Tp> {
469561 using __optional_storage_base<_Tp>::__optional_storage_base;
470562};
......@@ -484,7 +576,7 @@ struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp> {
484576 _LIBCPP_HIDE_FROM_ABI __optional_copy_base& operator=(__optional_copy_base&&) = default;
485577};
486578
487template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
579template <class _Tp, bool = is_trivially_move_constructible_v<_Tp> || is_lvalue_reference_v<_Tp>>
488580struct __optional_move_base : __optional_copy_base<_Tp> {
489581 using __optional_copy_base<_Tp>::__optional_copy_base;
490582};
......@@ -507,8 +599,9 @@ struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp> {
507599};
508600
509601template <class _Tp,
510 bool = is_trivially_destructible<_Tp>::value && is_trivially_copy_constructible<_Tp>::value &&
511 is_trivially_copy_assignable<_Tp>::value>
602 bool = (is_trivially_destructible_v<_Tp> && is_trivially_copy_constructible_v<_Tp> &&
603 is_trivially_copy_assignable_v<_Tp>) ||
604 is_lvalue_reference_v<_Tp>>
512605struct __optional_copy_assign_base : __optional_move_base<_Tp> {
513606 using __optional_move_base<_Tp>::__optional_move_base;
514607};
......@@ -531,8 +624,9 @@ struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp> {
531624};
532625
533626template <class _Tp,
534 bool = is_trivially_destructible<_Tp>::value && is_trivially_move_constructible<_Tp>::value &&
535 is_trivially_move_assignable<_Tp>::value>
627 bool = (is_trivially_destructible_v<_Tp> && is_trivially_move_constructible_v<_Tp> &&
628 is_trivially_move_assignable_v<_Tp>) ||
629 is_lvalue_reference_v<_Tp>>
536630struct __optional_move_assign_base : __optional_copy_assign_base<_Tp> {
537631 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
538632};
......@@ -561,12 +655,24 @@ using __optional_sfinae_ctor_base_t _LIBCPP_NODEBUG =
561655
562656template <class _Tp>
563657using __optional_sfinae_assign_base_t _LIBCPP_NODEBUG =
564 __sfinae_assign_base< (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
565 (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value) >;
658 __sfinae_assign_base< (is_copy_constructible_v<_Tp> && is_copy_assignable_v<_Tp>) || is_lvalue_reference_v<_Tp>,
659 (is_move_constructible_v<_Tp> && is_move_assignable_v<_Tp>) || is_lvalue_reference_v<_Tp>>;
566660
567661template <class _Tp>
568662class optional;
569663
664# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPERIMENTAL_OPTIONAL_ITERATOR
665template <class _Tp>
666constexpr bool ranges::enable_view<optional<_Tp>> = true;
667
668template <class _Tp>
669constexpr range_format format_kind<optional<_Tp>> = range_format::disabled;
670
671template <class _Tp>
672constexpr bool ranges::enable_borrowed_range<optional<_Tp&>> = true;
673
674# endif
675
570676# if _LIBCPP_STD_VER >= 20
571677
572678template <class _Tp>
......@@ -579,29 +685,150 @@ struct __is_std_optional : false_type {};
579685template <class _Tp>
580686struct __is_std_optional<optional<_Tp>> : true_type {};
581687
688template <class _Tp, class... _Args>
689inline constexpr bool __is_constructible_for_optional_v = is_constructible_v<_Tp, _Args...>;
690
691template <class _Tp, class... _Args>
692struct __is_constructible_for_optional : bool_constant<__is_constructible_for_optional_v<_Tp, _Args...>> {};
693
694template <class _Tp, class _Up, class... _Args>
695inline constexpr bool __is_constructible_for_optional_initializer_list_v =
696 is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>;
697
698# if _LIBCPP_STD_VER >= 26
699template <class _Tp, class... _Args>
700inline constexpr bool __is_constructible_for_optional_v<_Tp&, _Args...> = false;
701template <class _Tp, class _Arg>
702inline constexpr bool __is_constructible_for_optional_v<_Tp&, _Arg> =
703 is_constructible_v<_Tp&, _Arg> && !reference_constructs_from_temporary_v<_Tp&, _Arg>;
704
705template <class _Tp, class _Up, class... _Args>
706inline constexpr bool __is_constructible_for_optional_initializer_list_v<_Tp&, _Up, _Args...> = false;
707# endif
708
709template <class _Tp, class = void>
710struct __optional_iterator {};
711
712# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPERIMENTAL_OPTIONAL_ITERATOR
713
714template <class _Tp>
715struct __optional_iterator<_Tp, enable_if_t<is_object_v<_Tp>>> {
716private:
717 using __pointer _LIBCPP_NODEBUG = add_pointer_t<_Tp>;
718 using __const_pointer _LIBCPP_NODEBUG = add_pointer_t<const _Tp>;
719
720public:
721# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
722 using iterator = __bounded_iter<__wrap_iter<__pointer>>;
723 using const_iterator = __bounded_iter<__wrap_iter<__const_pointer>>;
724# else
725 using iterator = __wrap_iter<__pointer>;
726 using const_iterator = __wrap_iter<__const_pointer>;
727# endif
728
729 // [optional.iterators], iterator support
730 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() noexcept {
731 auto& __derived_self = static_cast<optional<_Tp>&>(*this);
732 auto* __ptr = std::addressof(__derived_self.__get());
733
734# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
735 return std::__make_bounded_iter(
736 __wrap_iter<__pointer>(__ptr),
737 __wrap_iter<__pointer>(__ptr),
738 __wrap_iter<__pointer>(__ptr) + (__derived_self.has_value() ? 1 : 0));
739# else
740 return iterator(__ptr);
741# endif
742 }
743
744 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept {
745 auto& __derived_self = static_cast<const optional<_Tp>&>(*this);
746 auto* __ptr = std::addressof(__derived_self.__get());
747
748# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
749 return std::__make_bounded_iter(
750 __wrap_iter<__const_pointer>(__ptr),
751 __wrap_iter<__const_pointer>(__ptr),
752 __wrap_iter<__const_pointer>(__ptr) + (__derived_self.has_value() ? 1 : 0));
753# else
754 return const_iterator(__ptr);
755# endif
756 }
757
758 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() noexcept {
759 return begin() + (static_cast<optional<_Tp>&>(*this).has_value() ? 1 : 0);
760 }
761 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept {
762 return begin() + (static_cast<const optional<_Tp>&>(*this).has_value() ? 1 : 0);
763 }
764};
765
766template <class _Tp>
767struct __optional_iterator<_Tp&, enable_if_t<is_object_v<_Tp> && !__is_unbounded_array_v<_Tp> >> {
768private:
769 using __pointer _LIBCPP_NODEBUG = add_pointer_t<_Tp>;
770
771public:
772# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
773 using iterator = __bounded_iter<__wrap_iter<__pointer>>;
774# else
775 using iterator = __wrap_iter<__pointer>;
776# endif
777
778 // [optional.ref.iterators], iterator support
779
780 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const noexcept {
781 auto& __derived_self = static_cast<const optional<_Tp&>&>(*this);
782 auto* __ptr = __derived_self.has_value() ? std::addressof(__derived_self.__get()) : nullptr;
783
784# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
785 return std::__make_bounded_iter(
786 __wrap_iter<__pointer>(__ptr),
787 __wrap_iter<__pointer>(__ptr),
788 __wrap_iter<__pointer>(__ptr) + (__derived_self.has_value() ? 1 : 0));
789# else
790 return iterator(__ptr);
791# endif
792 }
793
794 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const noexcept {
795 return begin() + (static_cast<const optional<_Tp&>&>(*this).has_value() ? 1 : 0);
796 }
797};
798
799# endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPERIMENTAL_OPTIONAL_ITERATOR
800
582801template <class _Tp>
583802class _LIBCPP_DECLSPEC_EMPTY_BASES optional
584803 : private __optional_move_assign_base<_Tp>,
585804 private __optional_sfinae_ctor_base_t<_Tp>,
586 private __optional_sfinae_assign_base_t<_Tp> {
805 private __optional_sfinae_assign_base_t<_Tp>,
806 public __optional_iterator<_Tp> {
587807 using __base _LIBCPP_NODEBUG = __optional_move_assign_base<_Tp>;
588808
589809public:
590 using value_type = _Tp;
810 using value_type = __libcpp_remove_reference_t<_Tp>;
591811
592812 using __trivially_relocatable _LIBCPP_NODEBUG =
593813 conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>;
594 using __replaceable _LIBCPP_NODEBUG = conditional_t<__is_replaceable_v<_Tp>, optional, void>;
595814
596815private:
597 // Disable the reference extension using this static assert.
598 static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>,
816 static_assert(!is_same_v<__remove_cvref_t<_Tp>, in_place_t>,
599817 "instantiation of optional with in_place_t is ill-formed");
600 static_assert(!is_same_v<__remove_cvref_t<value_type>, nullopt_t>,
601 "instantiation of optional with nullopt_t is ill-formed");
602 static_assert(!is_reference_v<value_type>, "instantiation of optional with a reference type is ill-formed");
603 static_assert(is_destructible_v<value_type>, "instantiation of optional with a non-destructible type is ill-formed");
604 static_assert(!is_array_v<value_type>, "instantiation of optional with an array type is ill-formed");
818 static_assert(!is_same_v<__remove_cvref_t<_Tp>, nullopt_t>, "instantiation of optional with nullopt_t is ill-formed");
819# if _LIBCPP_STD_VER >= 26
820 static_assert(!is_rvalue_reference_v<_Tp>, "instantiation of optional with an rvalue reference type is ill-formed");
821# else
822 static_assert(!is_reference_v<_Tp>, "instantiation of optional with a reference type is ill-formed");
823# endif
824 static_assert(is_destructible_v<_Tp>, "instantiation of optional with a non-destructible type is ill-formed");
825 static_assert(!is_array_v<_Tp>, "instantiation of optional with an array type is ill-formed");
826
827# if _LIBCPP_STD_VER >= 26
828 template <class _Up>
829 constexpr static bool __libcpp_opt_ref_ctor_deleted =
830 is_lvalue_reference_v<_Tp> && reference_constructs_from_temporary_v<_Tp, _Up>;
831# endif
605832
606833 // LWG2756: conditionally explicit conversion from _Up
607834 struct _CheckOptionalArgsConstructor {
......@@ -674,45 +901,131 @@ public:
674901 _LIBCPP_HIDE_FROM_ABI constexpr optional(optional&&) = default;
675902 _LIBCPP_HIDE_FROM_ABI constexpr optional(nullopt_t) noexcept {}
676903
677 template <class _InPlaceT,
678 class... _Args,
679 enable_if_t<_And<_IsSame<_InPlaceT, in_place_t>, is_constructible<value_type, _Args...>>::value, int> = 0>
904 template <
905 class _InPlaceT,
906 class... _Args,
907 enable_if_t<_And<_IsSame<_InPlaceT, in_place_t>, __is_constructible_for_optional<_Tp, _Args...>>::value, int> = 0>
680908 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_InPlaceT, _Args&&... __args)
681909 : __base(in_place, std::forward<_Args>(__args)...) {}
682910
683911 template <class _Up,
684912 class... _Args,
685 enable_if_t<is_constructible_v<value_type, initializer_list<_Up>&, _Args...>, int> = 0>
913 enable_if_t<__is_constructible_for_optional_initializer_list_v<_Tp, _Up, _Args...>, int> = 0>
686914 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
687915 : __base(in_place, __il, std::forward<_Args>(__args)...) {}
688916
689 template <class _Up = value_type,
690 enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0>
691 _LIBCPP_HIDE_FROM_ABI constexpr optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
917 template <class _Up = _Tp, enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0>
918 _LIBCPP_HIDE_FROM_ABI constexpr optional(_Up&& __v)
919# if _LIBCPP_STD_VER >= 26
920 noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up>)
921# endif
922 : __base(in_place, std::forward<_Up>(__v)) {
923 }
692924
693 template <class _Up, enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0>
694 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
925 template <class _Up = remove_cv_t<_Tp>,
926 enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0>
927 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Up&& __v)
928# if _LIBCPP_STD_VER >= 26
929 noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up>)
930# endif
931 : __base(in_place, std::forward<_Up>(__v)) {
932 }
695933
696934 // LWG2756: conditionally explicit conversion from const optional<_Up>&
697935 template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>(), int> = 0>
698 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v) {
936 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v)
937# if _LIBCPP_STD_VER >= 26
938 noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up&>)
939# endif
940 {
699941 this->__construct_from(__v);
700942 }
701943 template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>(), int> = 0>
702 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v) {
944 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v)
945# if _LIBCPP_STD_VER >= 26
946 noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up&>)
947# endif
948 {
703949 this->__construct_from(__v);
704950 }
705951
706952 // LWG2756: conditionally explicit conversion from optional<_Up>&&
707953 template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_implicit<_Up>(), int> = 0>
708 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v) {
954 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v)
955# if _LIBCPP_STD_VER >= 26
956 noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up>)
957# endif
958 {
709959 this->__construct_from(std::move(__v));
710960 }
711961 template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_explicit<_Up>(), int> = 0>
712 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v) {
962 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v)
963# if _LIBCPP_STD_VER >= 26
964 noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up>)
965# endif
966 {
713967 this->__construct_from(std::move(__v));
714968 }
715969
970 // deleted optional<T&> constructors and additional optional<T&> constructors
971# if _LIBCPP_STD_VER >= 26
972 // optional(U&&)
973 template <class _Up = _Tp, enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0>
974 requires __libcpp_opt_ref_ctor_deleted<_Up>
975 optional(_Up&&) = delete;
976
977 template <class _Up = remove_cv_t<_Tp>,
978 enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0>
979 requires __libcpp_opt_ref_ctor_deleted<_Up>
980 explicit optional(_Up&&) = delete;
981
982 // optional(optional<U>& rhs)
983 template <class _Up>
984 requires(!__libcpp_opt_ref_ctor_deleted<_Up>) && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
985 (!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, _Up&>
986 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up&, _Tp&>)
987 optional(optional<_Up>& __rhs) noexcept(is_nothrow_constructible_v<_Tp&, _Up&>) {
988 this->__construct_from(__rhs);
989 }
990
991 template <class _Up>
992 requires __libcpp_opt_ref_ctor_deleted<_Up> && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
993 (!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, _Up&>
994 constexpr explicit optional(optional<_Up>& __rhs) noexcept = delete;
995
996 // optional(const optional<U>&)
997 template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>(), int> = 0>
998 requires __libcpp_opt_ref_ctor_deleted<_Up>
999 optional(const optional<_Up>&) = delete;
1000
1001 template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>(), int> = 0>
1002 requires __libcpp_opt_ref_ctor_deleted<_Up>
1003 explicit optional(const optional<_Up>&) = delete;
1004
1005 // optional(optional<U>&&)
1006 template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_implicit<_Up>(), int> = 0>
1007 requires __libcpp_opt_ref_ctor_deleted<_Up>
1008 optional(optional<_Up>&&) = delete;
1009
1010 template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_explicit<_Up>(), int> = 0>
1011 requires __libcpp_opt_ref_ctor_deleted<_Up>
1012 explicit optional(optional<_Up>&&) = delete;
1013
1014 // optional(const optional<U>&&)
1015 template <class _Up>
1016 requires(!__libcpp_opt_ref_ctor_deleted<_Up>) && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
1017 (!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, _Up>
1018 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(!is_convertible_v<const _Up, _Tp&>)
1019 optional(const optional<_Up>&& __v) noexcept(is_nothrow_constructible_v<_Tp&, const _Up>) {
1020 this->__construct_from(std::move(__v));
1021 }
1022
1023 template <class _Up>
1024 requires __libcpp_opt_ref_ctor_deleted<_Up> && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
1025 (!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, _Up>
1026 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>&& __v) noexcept = delete;
1027# endif
1028
7161029# if _LIBCPP_STD_VER >= 23
7171030 template <class _Tag,
7181031 class _Fp,
......@@ -731,11 +1044,12 @@ public:
7311044 _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default;
7321045
7331046 // LWG2756
734 template <class _Up = value_type,
1047 template <class _Up = remove_cv_t<_Tp>,
7351048 enable_if_t<_And<_IsNotSame<__remove_cvref_t<_Up>, optional>,
736 _Or<_IsNotSame<__remove_cvref_t<_Up>, value_type>, _Not<is_scalar<value_type>>>,
737 is_constructible<value_type, _Up>,
738 is_assignable<value_type&, _Up>>::value,
1049 _Or<_IsNotSame<__remove_cvref_t<_Up>, _Tp>, _Not<is_scalar<_Tp>>>,
1050 is_constructible<_Tp, _Up>,
1051 is_assignable<_Tp&, _Up>,
1052 is_object<_Tp>>::value,
7391053 int> = 0>
7401054 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(_Up&& __v) {
7411055 if (this->has_value())
......@@ -759,8 +1073,12 @@ public:
7591073 return *this;
7601074 }
7611075
762 template <class... _Args, enable_if_t<is_constructible_v<value_type, _Args...>, int> = 0>
763 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) {
1076 template <class... _Args, enable_if_t<__is_constructible_for_optional_v<_Tp, _Args...>, int> = 0>
1077 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args)
1078# if _LIBCPP_STD_VER >= 26
1079 noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp, _Args...>)
1080# endif
1081 {
7641082 reset();
7651083 this->__construct(std::forward<_Args>(__args)...);
7661084 return this->__get();
......@@ -768,56 +1086,72 @@ public:
7681086
7691087 template <class _Up,
7701088 class... _Args,
771 enable_if_t<is_constructible_v<value_type, initializer_list<_Up>&, _Args...>, int> = 0>
1089 enable_if_t<__is_constructible_for_optional_initializer_list_v<_Tp, _Up, _Args...>, int> = 0>
7721090 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
7731091 reset();
7741092 this->__construct(__il, std::forward<_Args>(__args)...);
7751093 return this->__get();
7761094 }
7771095
778 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
779 swap(optional& __opt) noexcept(is_nothrow_move_constructible_v<value_type> && is_nothrow_swappable_v<value_type>) {
780 if (this->has_value() == __opt.has_value()) {
781 using std::swap;
782 if (this->has_value())
783 swap(this->__get(), __opt.__get());
784 } else {
785 if (this->has_value()) {
786 __opt.__construct(std::move(this->__get()));
787 reset();
788 } else {
789 this->__construct(std::move(__opt.__get()));
790 __opt.reset();
791 }
792 }
1096 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(optional& __opt) noexcept(
1097 (is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp>)
1098# if _LIBCPP_STD_VER >= 26
1099 || is_lvalue_reference_v<_Tp>
1100# endif
1101 ) {
1102 this->__swap(__opt);
7931103 }
7941104
795 _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type const> operator->() const noexcept {
1105 _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp const> operator->() const noexcept
1106# if _LIBCPP_STD_VER >= 26
1107 requires(is_object_v<_Tp>)
1108# endif
1109 {
7961110 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
7971111 return std::addressof(this->__get());
7981112 }
7991113
800 _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type> operator->() noexcept {
1114 _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp> operator->() noexcept
1115# if _LIBCPP_STD_VER >= 26
1116 requires(is_object_v<_Tp>)
1117# endif
1118 {
8011119 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
8021120 return std::addressof(this->__get());
8031121 }
8041122
805 _LIBCPP_HIDE_FROM_ABI constexpr const value_type& operator*() const& noexcept {
1123 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept
1124# if _LIBCPP_STD_VER >= 26
1125 requires(is_object_v<_Tp>)
1126# endif
1127 {
8061128 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
8071129 return this->__get();
8081130 }
8091131
810 _LIBCPP_HIDE_FROM_ABI constexpr value_type& operator*() & noexcept {
1132 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept
1133# if _LIBCPP_STD_VER >= 26
1134 requires(is_object_v<_Tp>)
1135# endif
1136 {
8111137 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
8121138 return this->__get();
8131139 }
8141140
815 _LIBCPP_HIDE_FROM_ABI constexpr value_type&& operator*() && noexcept {
1141 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept
1142# if _LIBCPP_STD_VER >= 26
1143 requires(is_object_v<_Tp>)
1144# endif
1145 {
8161146 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
8171147 return std::move(this->__get());
8181148 }
8191149
820 _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& operator*() const&& noexcept {
1150 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept
1151# if _LIBCPP_STD_VER >= 26
1152 requires(is_object_v<_Tp>)
1153# endif
1154 {
8211155 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
8221156 return std::move(this->__get());
8231157 }
......@@ -827,48 +1161,73 @@ public:
8271161 using __base::__get;
8281162 using __base::has_value;
8291163
830 _LIBCPP_HIDE_FROM_ABI constexpr value_type const& value() const& {
1164 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& value() const&
1165# if _LIBCPP_STD_VER >= 26
1166 requires(is_object_v<_Tp>)
1167# endif
1168 {
8311169 if (!this->has_value())
8321170 std::__throw_bad_optional_access();
8331171 return this->__get();
8341172 }
8351173
836 _LIBCPP_HIDE_FROM_ABI constexpr value_type& value() & {
1174 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() &
1175# if _LIBCPP_STD_VER >= 26
1176 requires(is_object_v<_Tp>)
1177# endif
1178 {
8371179 if (!this->has_value())
8381180 std::__throw_bad_optional_access();
8391181 return this->__get();
8401182 }
8411183
842 _LIBCPP_HIDE_FROM_ABI constexpr value_type&& value() && {
1184 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() &&
1185# if _LIBCPP_STD_VER >= 26
1186 requires(is_object_v<_Tp>)
1187# endif
1188 {
8431189 if (!this->has_value())
8441190 std::__throw_bad_optional_access();
8451191 return std::move(this->__get());
8461192 }
8471193
848 _LIBCPP_HIDE_FROM_ABI constexpr value_type const&& value() const&& {
1194 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp const&& value() const&&
1195# if _LIBCPP_STD_VER >= 26
1196 requires(is_object_v<_Tp>)
1197# endif
1198 {
8491199 if (!this->has_value())
8501200 std::__throw_bad_optional_access();
8511201 return std::move(this->__get());
8521202 }
8531203
854 template <class _Up>
855 _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) const& {
856 static_assert(is_copy_constructible_v<value_type>, "optional<T>::value_or: T must be copy constructible");
857 static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T");
858 return this->has_value() ? this->__get() : static_cast<value_type>(std::forward<_Up>(__v));
1204 template <class _Up = remove_cv_t<_Tp>>
1205# if _LIBCPP_STD_VER >= 26
1206 requires(is_object_v<_Tp>)
1207# endif
1208 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& {
1209 static_assert(is_copy_constructible_v<_Tp>, "optional<T>::value_or: T must be copy constructible");
1210 static_assert(is_convertible_v<_Up, _Tp>, "optional<T>::value_or: U must be convertible to T");
1211 return this->has_value() ? this->__get() : static_cast<_Tp>(std::forward<_Up>(__v));
8591212 }
8601213
861 template <class _Up>
862 _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) && {
863 static_assert(is_move_constructible_v<value_type>, "optional<T>::value_or: T must be move constructible");
864 static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T");
865 return this->has_value() ? std::move(this->__get()) : static_cast<value_type>(std::forward<_Up>(__v));
1214 template <class _Up = remove_cv_t<_Tp>>
1215# if _LIBCPP_STD_VER >= 26
1216 requires(is_object_v<_Tp>)
1217# endif
1218 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
1219 static_assert(is_move_constructible_v<_Tp>, "optional<T>::value_or: T must be move constructible");
1220 static_assert(is_convertible_v<_Up, _Tp>, "optional<T>::value_or: U must be convertible to T");
1221 return this->has_value() ? std::move(this->__get()) : static_cast<_Tp>(std::forward<_Up>(__v));
8661222 }
8671223
8681224# if _LIBCPP_STD_VER >= 23
8691225 template <class _Func>
870 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
871 using _Up = invoke_result_t<_Func, value_type&>;
1226# if _LIBCPP_STD_VER >= 26
1227 requires(is_object_v<_Tp>)
1228# endif
1229 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
1230 using _Up = invoke_result_t<_Func, _Tp&>;
8721231 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
8731232 "Result of f(value()) must be a specialization of std::optional");
8741233 if (*this)
......@@ -877,8 +1236,11 @@ public:
8771236 }
8781237
8791238 template <class _Func>
880 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
881 using _Up = invoke_result_t<_Func, const value_type&>;
1239# if _LIBCPP_STD_VER >= 26
1240 requires(is_object_v<_Tp>)
1241# endif
1242 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
1243 using _Up = invoke_result_t<_Func, const _Tp&>;
8821244 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
8831245 "Result of f(value()) must be a specialization of std::optional");
8841246 if (*this)
......@@ -887,8 +1249,11 @@ public:
8871249 }
8881250
8891251 template <class _Func>
890 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
891 using _Up = invoke_result_t<_Func, value_type&&>;
1252# if _LIBCPP_STD_VER >= 26
1253 requires(is_object_v<_Tp>)
1254# endif
1255 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
1256 using _Up = invoke_result_t<_Func, _Tp&&>;
8921257 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
8931258 "Result of f(std::move(value())) must be a specialization of std::optional");
8941259 if (*this)
......@@ -897,8 +1262,11 @@ public:
8971262 }
8981263
8991264 template <class _Func>
900 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
901 using _Up = invoke_result_t<_Func, const value_type&&>;
1265# if _LIBCPP_STD_VER >= 26
1266 requires(is_object_v<_Tp>)
1267# endif
1268 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
1269 using _Up = invoke_result_t<_Func, const _Tp&&>;
9021270 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
9031271 "Result of f(std::move(value())) must be a specialization of std::optional");
9041272 if (*this)
......@@ -907,8 +1275,11 @@ public:
9071275 }
9081276
9091277 template <class _Func>
910 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
911 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>;
1278# if _LIBCPP_STD_VER >= 26
1279 requires(is_object_v<_Tp>)
1280# endif
1281 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
1282 using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&>>;
9121283 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
9131284 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t");
9141285 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t");
......@@ -919,8 +1290,11 @@ public:
9191290 }
9201291
9211292 template <class _Func>
922 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
923 using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>;
1293# if _LIBCPP_STD_VER >= 26
1294 requires(is_object_v<_Tp>)
1295# endif
1296 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
1297 using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&>>;
9241298 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
9251299 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t");
9261300 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t");
......@@ -931,8 +1305,11 @@ public:
9311305 }
9321306
9331307 template <class _Func>
934 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
935 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>;
1308# if _LIBCPP_STD_VER >= 26
1309 requires(is_object_v<_Tp>)
1310# endif
1311 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
1312 using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&&>>;
9361313 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
9371314 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t");
9381315 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t");
......@@ -943,8 +1320,11 @@ public:
9431320 }
9441321
9451322 template <class _Func>
946 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
947 using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>;
1323# if _LIBCPP_STD_VER >= 26
1324 requires(is_object_v<_Tp>)
1325# endif
1326 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
1327 using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&&>>;
9481328 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
9491329 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t");
9501330 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t");
......@@ -955,8 +1335,11 @@ public:
9551335 }
9561336
9571337 template <invocable _Func>
958 _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const&
959 requires is_copy_constructible_v<value_type>
1338 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const&
1339 requires is_copy_constructible_v<_Tp>
1340# if _LIBCPP_STD_VER >= 26
1341 && (is_object_v<_Tp>)
1342# endif
9601343 {
9611344 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
9621345 "Result of f() should be the same type as this optional");
......@@ -966,8 +1349,11 @@ public:
9661349 }
9671350
9681351 template <invocable _Func>
969 _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) &&
970 requires is_move_constructible_v<value_type>
1352 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) &&
1353 requires is_move_constructible_v<_Tp>
1354# if _LIBCPP_STD_VER >= 26
1355 && (is_object_v<_Tp>)
1356# endif
9711357 {
9721358 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
9731359 "Result of f() should be the same type as this optional");
......@@ -978,6 +1364,78 @@ public:
9781364# endif // _LIBCPP_STD_VER >= 23
9791365
9801366 using __base::reset;
1367
1368// optional<T&> overloads
1369# if _LIBCPP_STD_VER >= 26
1370
1371 _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp> operator->() const noexcept
1372 requires(is_lvalue_reference_v<_Tp>)
1373 {
1374 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
1375 return std::addressof(this->__get());
1376 }
1377
1378 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() const noexcept
1379 requires(is_lvalue_reference_v<_Tp>)
1380 {
1381 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
1382 return this->__get();
1383 }
1384
1385 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() const
1386 requires(is_lvalue_reference_v<_Tp>)
1387 {
1388 if (!this->has_value())
1389 std::__throw_bad_optional_access();
1390 return this->__get();
1391 }
1392
1393 template <class _Up = remove_cvref_t<_Tp>>
1394 requires(is_lvalue_reference_v<_Tp> && is_object_v<__libcpp_remove_reference_t<_Tp>> &&
1395 !is_array_v<__libcpp_remove_reference_t<_Tp>>)
1396 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decay_t<_Tp> value_or(_Up&& __v) const {
1397 static_assert(
1398 is_constructible_v<remove_cvref_t<_Tp>, _Tp&>, "optional<T&>::value_or: remove_cv_t<T> must be constructible");
1399 static_assert(
1400 is_convertible_v<_Up, remove_cvref_t<_Tp>>, "optional<T&>::value_or: U must be convertible to remove_cv_t<T>");
1401 return this->has_value() ? this->__get() : static_cast<remove_cvref_t<_Tp>>(std::forward<_Up>(__v));
1402 }
1403
1404 template <class _Func>
1405 requires(is_lvalue_reference_v<_Tp>)
1406 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const {
1407 using _Up = invoke_result_t<_Func, _Tp&>;
1408 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1409 "Result of f(value()) must be a specialization of std::optional");
1410 if (*this)
1411 return std::invoke(std::forward<_Func>(__f), value());
1412 return remove_cvref_t<_Up>();
1413 }
1414
1415 template <class _Func>
1416 requires(is_lvalue_reference_v<_Tp>)
1417 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional<remove_cv_t<invoke_result_t<_Func, _Tp&>>>
1418 transform(_Func&& __f) const {
1419 using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&>>;
1420 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
1421 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t");
1422 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t");
1423 static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
1424 if (*this)
1425 return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value());
1426 return optional<_Up>();
1427 }
1428
1429 template <invocable _Func>
1430 requires(is_lvalue_reference_v<_Tp>)
1431 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const {
1432 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
1433 "Result of f() should be the same type as this optional");
1434 if (*this)
1435 return *this;
1436 return std::forward<_Func>(__f)();
1437 }
1438# endif
9811439};
9821440
9831441template <class _Tp>
......@@ -1154,7 +1612,9 @@ template <
11541612 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>,
11551613 int> = 0>
11561614_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const _Up& __v) {
1157 return static_cast<bool>(__x) ? *__x == __v : false;
1615 if (__x.has_value())
1616 return *__x == __v;
1617 return false;
11581618}
11591619
11601620template <
......@@ -1163,7 +1623,9 @@ template <
11631623 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>,
11641624 int> = 0>
11651625_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const _Tp& __v, const optional<_Up>& __x) {
1166 return static_cast<bool>(__x) ? __v == *__x : false;
1626 if (__x.has_value())
1627 return __v == *__x;
1628 return false;
11671629}
11681630
11691631template <
......@@ -1172,7 +1634,9 @@ template <
11721634 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>,
11731635 int> = 0>
11741636_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const _Up& __v) {
1175 return static_cast<bool>(__x) ? *__x != __v : true;
1637 if (__x.has_value())
1638 return *__x != __v;
1639 return true;
11761640}
11771641
11781642template <
......@@ -1181,7 +1645,9 @@ template <
11811645 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>,
11821646 int> = 0>
11831647_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const _Tp& __v, const optional<_Up>& __x) {
1184 return static_cast<bool>(__x) ? __v != *__x : true;
1648 if (__x.has_value())
1649 return __v != *__x;
1650 return true;
11851651}
11861652
11871653template < class _Tp,
......@@ -1189,7 +1655,9 @@ template < class _Tp,
11891655 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>,
11901656 int> = 0>
11911657_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const _Up& __v) {
1192 return static_cast<bool>(__x) ? *__x < __v : true;
1658 if (__x.has_value())
1659 return *__x < __v;
1660 return true;
11931661}
11941662
11951663template < class _Tp,
......@@ -1197,7 +1665,9 @@ template < class _Tp,
11971665 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>,
11981666 int> = 0>
11991667_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const _Tp& __v, const optional<_Up>& __x) {
1200 return static_cast<bool>(__x) ? __v < *__x : false;
1668 if (__x.has_value())
1669 return __v < *__x;
1670 return false;
12011671}
12021672
12031673template <
......@@ -1206,7 +1676,9 @@ template <
12061676 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>,
12071677 int> = 0>
12081678_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const _Up& __v) {
1209 return static_cast<bool>(__x) ? *__x <= __v : true;
1679 if (__x.has_value())
1680 return *__x <= __v;
1681 return true;
12101682}
12111683
12121684template <
......@@ -1215,7 +1687,9 @@ template <
12151687 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>,
12161688 int> = 0>
12171689_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const _Tp& __v, const optional<_Up>& __x) {
1218 return static_cast<bool>(__x) ? __v <= *__x : false;
1690 if (__x.has_value())
1691 return __v <= *__x;
1692 return false;
12191693}
12201694
12211695template < class _Tp,
......@@ -1223,7 +1697,9 @@ template < class _Tp,
12231697 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>,
12241698 int> = 0>
12251699_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const _Up& __v) {
1226 return static_cast<bool>(__x) ? *__x > __v : false;
1700 if (__x.has_value())
1701 return *__x > __v;
1702 return false;
12271703}
12281704
12291705template < class _Tp,
......@@ -1231,7 +1707,9 @@ template < class _Tp,
12311707 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>,
12321708 int> = 0>
12331709_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const _Tp& __v, const optional<_Up>& __x) {
1234 return static_cast<bool>(__x) ? __v > *__x : true;
1710 if (__x.has_value())
1711 return __v > *__x;
1712 return true;
12351713}
12361714
12371715template <
......@@ -1240,7 +1718,9 @@ template <
12401718 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>,
12411719 int> = 0>
12421720_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const _Up& __v) {
1243 return static_cast<bool>(__x) ? *__x >= __v : false;
1721 if (__x.has_value())
1722 return *__x >= __v;
1723 return false;
12441724}
12451725
12461726template <
......@@ -1249,7 +1729,9 @@ template <
12491729 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>,
12501730 int> = 0>
12511731_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const _Tp& __v, const optional<_Up>& __x) {
1252 return static_cast<bool>(__x) ? __v >= *__x : true;
1732 if (__x.has_value())
1733 return __v >= *__x;
1734 return true;
12531735}
12541736
12551737# if _LIBCPP_STD_VER >= 20
......@@ -1264,23 +1746,36 @@ operator<=>(const optional<_Tp>& __x, const _Up& __v) {
12641746# endif // _LIBCPP_STD_VER >= 20
12651747
12661748template <class _Tp, enable_if_t< is_move_constructible_v<_Tp> && is_swappable_v<_Tp>, int> = 0>
1267inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
1268swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) {
1749inline _LIBCPP_HIDE_FROM_ABI
1750_LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) {
12691751 __x.swap(__y);
12701752}
12711753
1272template <class _Tp>
1273_LIBCPP_HIDE_FROM_ABI constexpr optional<decay_t<_Tp>> make_optional(_Tp&& __v) {
1754struct __make_optional_barrier_tag {
1755 explicit __make_optional_barrier_tag() = default;
1756};
1757
1758template <
1759# if _LIBCPP_STD_VER >= 26
1760 __make_optional_barrier_tag = __make_optional_barrier_tag{},
1761# endif
1762 class _Tp,
1763 enable_if_t<is_constructible_v<decay_t<_Tp>, _Tp>, int> = 0>
1764[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional<decay_t<_Tp>> make_optional(_Tp&& __v) {
12741765 return optional<decay_t<_Tp>>(std::forward<_Tp>(__v));
12751766}
12761767
1277template <class _Tp, class... _Args>
1278_LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(_Args&&... __args) {
1768template <class _Tp, class... _Args, enable_if_t<__is_constructible_for_optional_v<_Tp, _Args...>, int> = 0>
1769[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(_Args&&... __args) {
12791770 return optional<_Tp>(in_place, std::forward<_Args>(__args)...);
12801771}
12811772
1282template <class _Tp, class _Up, class... _Args>
1283_LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) {
1773template <class _Tp,
1774 class _Up,
1775 class... _Args,
1776 enable_if_t<__is_constructible_for_optional_initializer_list_v<_Tp, _Up, _Args...>, int> = 0>
1777[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp>
1778make_optional(initializer_list<_Up> __il, _Args&&... __args) {
12841779 return optional<_Tp>(in_place, __il, std::forward<_Args>(__args)...);
12851780}
12861781
......@@ -1291,7 +1786,7 @@ struct hash< __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>> > {
12911786 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
12921787# endif
12931788
1294 _LIBCPP_HIDE_FROM_ABI size_t operator()(const optional<_Tp>& __opt) const {
1789 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const optional<_Tp>& __opt) const {
12951790 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
12961791 }
12971792};
lib/libcxx/include/print+9-5
......@@ -329,7 +329,8 @@ __vprint_unicode([[maybe_unused]] FILE* __stream,
329329} // namespace __print
330330
331331template <class... _Args>
332_LIBCPP_HIDE_FROM_ABI void print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
332_LIBCPP_HIDE_FROM_ABI void
333print(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream, format_string<_Args...> __fmt, _Args&&... __args) {
333334# if _LIBCPP_HAS_UNICODE
334335 if constexpr (__print::__use_unicode_execution_charset)
335336 __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
......@@ -346,7 +347,8 @@ _LIBCPP_HIDE_FROM_ABI void print(format_string<_Args...> __fmt, _Args&&... __arg
346347}
347348
348349template <class... _Args>
349_LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
350_LIBCPP_HIDE_FROM_ABI void
351println(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream, format_string<_Args...> __fmt, _Args&&... __args) {
350352# if _LIBCPP_HAS_UNICODE
351353 // Note the wording in the Standard is inefficient. The output of
352354 // std::format is a std::string which is then copied. This solution
......@@ -361,7 +363,7 @@ _LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt
361363}
362364
363365template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
364_LIBCPP_HIDE_FROM_ABI inline void println(FILE* __stream) {
366_LIBCPP_HIDE_FROM_ABI inline void println(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream) {
365367 std::print(__stream, "\n");
366368}
367369
......@@ -377,7 +379,8 @@ _LIBCPP_HIDE_FROM_ABI void println(format_string<_Args...> __fmt, _Args&&... __a
377379
378380# if _LIBCPP_HAS_UNICODE
379381template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
380_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(FILE* __stream, string_view __fmt, format_args __args) {
382_LIBCPP_HIDE_FROM_ABI inline void
383vprint_unicode(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream, string_view __fmt, format_args __args) {
381384 __print::__vprint_unicode(__stream, __fmt, __args, false);
382385}
383386
......@@ -389,7 +392,8 @@ _LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(string_view __fmt, format_args
389392# endif // _LIBCPP_HAS_UNICODE
390393
391394template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
392_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args) {
395_LIBCPP_HIDE_FROM_ABI inline void
396vprint_nonunicode(FILE* _LIBCPP_DIAGNOSE_NULLPTR __stream, string_view __fmt, format_args __args) {
393397 __print::__vprint_nonunicode(__stream, __fmt, __args, false);
394398}
395399
lib/libcxx/include/queue+39-37
......@@ -376,12 +376,12 @@ public:
376376# endif // _LIBCPP_CXX03_LANG
377377
378378 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const { return c.empty(); }
379 _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); }
379 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); }
380380
381 _LIBCPP_HIDE_FROM_ABI reference front() { return c.front(); }
382 _LIBCPP_HIDE_FROM_ABI const_reference front() const { return c.front(); }
383 _LIBCPP_HIDE_FROM_ABI reference back() { return c.back(); }
384 _LIBCPP_HIDE_FROM_ABI const_reference back() const { return c.back(); }
381 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference front() { return c.front(); }
382 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference front() const { return c.front(); }
383 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference back() { return c.back(); }
384 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference back() const { return c.back(); }
385385
386386 _LIBCPP_HIDE_FROM_ABI void push(const value_type& __v) { c.push_back(__v); }
387387# ifndef _LIBCPP_CXX03_LANG
......@@ -437,19 +437,19 @@ public:
437437};
438438
439439# if _LIBCPP_STD_VER >= 17
440template <class _Container, class = enable_if_t<!__is_allocator<_Container>::value> >
440template <class _Container, class = enable_if_t<!__is_allocator_v<_Container>>>
441441queue(_Container) -> queue<typename _Container::value_type, _Container>;
442442
443443template <class _Container,
444444 class _Alloc,
445 class = enable_if_t<!__is_allocator<_Container>::value>,
445 class = enable_if_t<!__is_allocator_v<_Container>>,
446446 class = enable_if_t<uses_allocator<_Container, _Alloc>::value> >
447447queue(_Container, _Alloc) -> queue<typename _Container::value_type, _Container>;
448448# endif
449449
450450# if _LIBCPP_STD_VER >= 23
451451template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
452queue(_InputIterator, _InputIterator) -> queue<__iter_value_type<_InputIterator>>;
452queue(_InputIterator, _InputIterator) -> queue<__iterator_value_type<_InputIterator>>;
453453
454454template <ranges::input_range _Range>
455455queue(from_range_t, _Range&&) -> queue<ranges::range_value_t<_Range>>;
......@@ -457,11 +457,11 @@ queue(from_range_t, _Range&&) -> queue<ranges::range_value_t<_Range>>;
457457template <class _InputIterator,
458458 class _Alloc,
459459 __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0,
460 __enable_if_t<__is_allocator<_Alloc>::value, int> = 0>
460 __enable_if_t<__is_allocator_v<_Alloc>, int> = 0>
461461queue(_InputIterator, _InputIterator, _Alloc)
462 -> queue<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>;
462 -> queue<__iterator_value_type<_InputIterator>, deque<__iterator_value_type<_InputIterator>, _Alloc>>;
463463
464template <ranges::input_range _Range, class _Alloc, __enable_if_t<__is_allocator<_Alloc>::value, int> = 0>
464template <ranges::input_range _Range, class _Alloc, __enable_if_t<__is_allocator_v<_Alloc>, int> = 0>
465465queue(from_range_t, _Range&&, _Alloc)
466466 -> queue<ranges::range_value_t<_Range>, deque<ranges::range_value_t<_Range>, _Alloc>>;
467467# endif
......@@ -664,8 +664,10 @@ public:
664664# endif
665665
666666 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool empty() const { return c.empty(); }
667 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); }
668 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference top() const { return c.front(); }
667 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); }
668 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference top() const {
669 return c.front();
670 }
669671
670672 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void push(const value_type& __v);
671673# ifndef _LIBCPP_CXX03_LANG
......@@ -700,45 +702,45 @@ public:
700702# if _LIBCPP_STD_VER >= 17
701703template <class _Compare,
702704 class _Container,
703 class = enable_if_t<!__is_allocator<_Compare>::value>,
704 class = enable_if_t<!__is_allocator<_Container>::value> >
705 class = enable_if_t<!__is_allocator_v<_Compare>>,
706 class = enable_if_t<!__is_allocator_v<_Container>>>
705707priority_queue(_Compare, _Container) -> priority_queue<typename _Container::value_type, _Container, _Compare>;
706708
707709template <class _InputIterator,
708 class _Compare = less<__iter_value_type<_InputIterator>>,
709 class _Container = vector<__iter_value_type<_InputIterator>>,
710 class _Compare = less<__iterator_value_type<_InputIterator>>,
711 class _Container = vector<__iterator_value_type<_InputIterator>>,
710712 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
711 class = enable_if_t<!__is_allocator<_Compare>::value>,
712 class = enable_if_t<!__is_allocator<_Container>::value> >
713 class = enable_if_t<!__is_allocator_v<_Compare>>,
714 class = enable_if_t<!__is_allocator_v<_Container>>>
713715priority_queue(_InputIterator, _InputIterator, _Compare = _Compare(), _Container = _Container())
714 -> priority_queue<__iter_value_type<_InputIterator>, _Container, _Compare>;
716 -> priority_queue<__iterator_value_type<_InputIterator>, _Container, _Compare>;
715717
716718template <class _Compare,
717719 class _Container,
718720 class _Alloc,
719 class = enable_if_t<!__is_allocator<_Compare>::value>,
720 class = enable_if_t<!__is_allocator<_Container>::value>,
721 class = enable_if_t<uses_allocator<_Container, _Alloc>::value> >
721 class = enable_if_t<!__is_allocator_v<_Compare>>,
722 class = enable_if_t<!__is_allocator_v<_Container>>,
723 class = enable_if_t<uses_allocator<_Container, _Alloc>::value>>
722724priority_queue(_Compare, _Container, _Alloc) -> priority_queue<typename _Container::value_type, _Container, _Compare>;
723725
724726template <class _InputIterator,
725727 class _Allocator,
726728 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
727 class = enable_if_t<__is_allocator<_Allocator>::value> >
729 class = enable_if_t<__is_allocator_v<_Allocator>>>
728730priority_queue(_InputIterator, _InputIterator, _Allocator)
729 -> priority_queue<__iter_value_type<_InputIterator>,
730 vector<__iter_value_type<_InputIterator>, _Allocator>,
731 less<__iter_value_type<_InputIterator>>>;
731 -> priority_queue<__iterator_value_type<_InputIterator>,
732 vector<__iterator_value_type<_InputIterator>, _Allocator>,
733 less<__iterator_value_type<_InputIterator>>>;
732734
733735template <class _InputIterator,
734736 class _Compare,
735737 class _Allocator,
736738 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
737 class = enable_if_t<!__is_allocator<_Compare>::value>,
738 class = enable_if_t<__is_allocator<_Allocator>::value> >
739 class = enable_if_t<!__is_allocator_v<_Compare>>,
740 class = enable_if_t<__is_allocator_v<_Allocator>>>
739741priority_queue(_InputIterator, _InputIterator, _Compare, _Allocator)
740 -> priority_queue<__iter_value_type<_InputIterator>,
741 vector<__iter_value_type<_InputIterator>, _Allocator>,
742 -> priority_queue<__iterator_value_type<_InputIterator>,
743 vector<__iterator_value_type<_InputIterator>, _Allocator>,
742744 _Compare>;
743745
744746template <class _InputIterator,
......@@ -746,8 +748,8 @@ template <class _InputIterator,
746748 class _Container,
747749 class _Alloc,
748750 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
749 class = enable_if_t<!__is_allocator<_Compare>::value>,
750 class = enable_if_t<!__is_allocator<_Container>::value>,
751 class = enable_if_t<!__is_allocator_v<_Compare>>,
752 class = enable_if_t<!__is_allocator_v<_Container>>,
751753 class = enable_if_t<uses_allocator<_Container, _Alloc>::value> >
752754priority_queue(_InputIterator, _InputIterator, _Compare, _Container, _Alloc)
753755 -> priority_queue<typename _Container::value_type, _Container, _Compare>;
......@@ -757,19 +759,19 @@ priority_queue(_InputIterator, _InputIterator, _Compare, _Container, _Alloc)
757759
758760template <ranges::input_range _Range,
759761 class _Compare = less<ranges::range_value_t<_Range>>,
760 class = enable_if_t<!__is_allocator<_Compare>::value>>
762 class = enable_if_t<!__is_allocator_v<_Compare>>>
761763priority_queue(from_range_t, _Range&&, _Compare = _Compare())
762764 -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>>, _Compare>;
763765
764766template <ranges::input_range _Range,
765767 class _Compare,
766768 class _Alloc,
767 class = enable_if_t<!__is_allocator<_Compare>::value>,
768 class = enable_if_t<__is_allocator<_Alloc>::value>>
769 class = enable_if_t<!__is_allocator_v<_Compare>>,
770 class = enable_if_t<__is_allocator_v<_Alloc>>>
769771priority_queue(from_range_t, _Range&&, _Compare, _Alloc)
770772 -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>, _Compare>;
771773
772template <ranges::input_range _Range, class _Alloc, class = enable_if_t<__is_allocator<_Alloc>::value>>
774template <ranges::input_range _Range, class _Alloc, class = enable_if_t<__is_allocator_v<_Alloc>>>
773775priority_queue(from_range_t, _Range&&, _Alloc)
774776 -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>>;
775777
lib/libcxx/include/ranges+48
......@@ -116,6 +116,10 @@ namespace std::ranges {
116116 // [range.dangling], dangling iterator handling
117117 struct dangling;
118118
119 // [range.elementsof], class template elements_of
120 template<range R, class Allocator = allocator<byte>>
121 struct elements_of;
122
119123 template<range R>
120124 using borrowed_iterator_t = see below;
121125
......@@ -267,6 +271,11 @@ namespace std::ranges {
267271 template<class W, class Bound>
268272 inline constexpr bool enable_borrowed_range<iota_view<W, Bound>> = true;
269273
274 namespace views {
275 inline constexpr unspecified iota = unspecified;
276 inline constexpr unspecified indices = unspecified; // Since C++26
277 }
278
270279 // [range.repeat], repeat view
271280 template<class T>
272281 concept integer-like-with-usable-difference-type = // exposition only
......@@ -339,6 +348,41 @@ namespace std::ranges {
339348
340349 namespace views { inline constexpr unspecified zip = unspecified; } // C++23
341350
351 // [range.zip.transform], zip transform view
352 template<move_constructible F, input_range... Views>
353 requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
354 regular_invocable<F&, range_reference_t<Views>...> &&
355 can-reference<invoke_result_t<F&, range_reference_t<Views>...>>
356 class zip_transform_view; // C++23
357
358 namespace views { inline constexpr unspecified zip_transform = unspecified; } // C++23
359
360 // [range.adjacent], adjacent view
361 template<forward_range V, size_t N>
362 requires view<V> && (N > 0)
363 class adjacent_view;
364
365 template<class V, size_t N>
366 constexpr bool enable_borrowed_range<adjacent_view<V, N>> =
367 enable_borrowed_range<V>;
368
369 namespace views {
370 template<size_t N>
371 constexpr unspecified adjacent = unspecified;
372 inline constexpr auto pairwise = adjacent<2>;
373 }
374
375 // [range.adjacent.transform], adjacent transform view
376 template<forward_range V, move_constructible F, size_t N>
377 requires see below
378 class adjacent_transform_view;
379
380 namespace views {
381 template<size_t N>
382 constexpr unspecified adjacent_transform = unspecified;
383 inline constexpr auto pairwise_transform = adjacent_transform<2>;
384 }
385
342386 // [range.as.rvalue]
343387 template <view V>
344388 requires input_range<V>
......@@ -404,6 +448,7 @@ namespace std {
404448# include <__ranges/data.h>
405449# include <__ranges/drop_view.h>
406450# include <__ranges/drop_while_view.h>
451# include <__ranges/elements_of.h>
407452# include <__ranges/elements_view.h>
408453# include <__ranges/empty.h>
409454# include <__ranges/empty_view.h>
......@@ -433,12 +478,15 @@ namespace std {
433478# endif
434479
435480# if _LIBCPP_STD_VER >= 23
481# include <__ranges/adjacent_transform_view.h>
482# include <__ranges/adjacent_view.h>
436483# include <__ranges/as_rvalue_view.h>
437484# include <__ranges/chunk_by_view.h>
438485# include <__ranges/from_range.h>
439486# include <__ranges/join_with_view.h>
440487# include <__ranges/repeat_view.h>
441488# include <__ranges/to.h>
489# include <__ranges/zip_transform_view.h>
442490# include <__ranges/zip_view.h>
443491# endif
444492
lib/libcxx/include/regex+33-31
......@@ -986,7 +986,7 @@ public:
986986 explicit regex_error(regex_constants::error_type __ecode);
987987 _LIBCPP_HIDE_FROM_ABI regex_error(const regex_error&) _NOEXCEPT = default;
988988 ~regex_error() _NOEXCEPT override;
989 _LIBCPP_HIDE_FROM_ABI regex_constants::error_type code() const { return __code_; }
989 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI regex_constants::error_type code() const { return __code_; }
990990};
991991
992992template <regex_constants::error_type _Ev>
......@@ -1004,7 +1004,7 @@ public:
10041004 typedef _CharT char_type;
10051005 typedef basic_string<char_type> string_type;
10061006 typedef locale locale_type;
1007# if defined(__BIONIC__) || defined(_NEWLIB_VERSION)
1007# if defined(__BIONIC__) || _LIBCPP_LIBC_NEWLIB
10081008 // Originally bionic's ctype_base used its own ctype masks because the
10091009 // builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask
10101010 // was only 8 bits wide and already saturated, so it used a wider type here
......@@ -1013,9 +1013,7 @@ public:
10131013 // implementation, but this was not updated to match. Since then Android has
10141014 // needed to maintain a stable libc++ ABI, and this can't be changed without
10151015 // an ABI break.
1016 // We also need this workaround for newlib since _NEWLIB_VERSION is not
1017 // defined yet inside __config, so we can't set the
1018 // _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE macro. Additionally, newlib is
1016 // We also need this workaround for newlib since newlib is
10191017 // often used for space constrained environments, so it makes sense not to
10201018 // duplicate the ctype table.
10211019 typedef uint16_t char_class_type;
......@@ -2120,7 +2118,7 @@ public:
21202118 __ranges_.push_back(
21212119 std::make_pair(__traits_.transform(__b.begin(), __b.end()), __traits_.transform(__e.begin(), __e.end())));
21222120 } else {
2123 if (__b.size() != 1 || __e.size() != 1)
2121 if (__b.size() != 1 || __e.size() != 1 || char_traits<typename string_type::value_type>::lt(__e[0], __b[0]))
21242122 std::__throw_regex_error<regex_constants::error_range>();
21252123 if (__icase_) {
21262124 __b[0] = __traits_.translate_nocase(__b[0]);
......@@ -2414,8 +2412,8 @@ public:
24142412# endif // _LIBCPP_CXX03_LANG
24152413
24162414 // const operations:
2417 _LIBCPP_HIDE_FROM_ABI unsigned mark_count() const { return __marked_count_; }
2418 _LIBCPP_HIDE_FROM_ABI flag_type flags() const { return __flags_; }
2415 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI unsigned mark_count() const { return __marked_count_; }
2416 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI flag_type flags() const { return __flags_; }
24192417
24202418 // locale:
24212419 _LIBCPP_HIDE_FROM_ABI locale_type imbue(locale_type __loc) {
......@@ -2423,7 +2421,7 @@ public:
24232421 __start_.reset();
24242422 return __traits_.imbue(__loc);
24252423 }
2426 _LIBCPP_HIDE_FROM_ABI locale_type getloc() const { return __traits_.getloc(); }
2424 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI locale_type getloc() const { return __traits_.getloc(); }
24272425
24282426 // swap:
24292427 void swap(basic_regex& __r);
......@@ -4208,17 +4206,17 @@ public:
42084206
42094207 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR sub_match() : matched() {}
42104208
4211 _LIBCPP_HIDE_FROM_ABI difference_type length() const {
4209 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI difference_type length() const {
42124210 return matched ? std::distance(this->first, this->second) : 0;
42134211 }
4214 _LIBCPP_HIDE_FROM_ABI string_type str() const {
4212 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type str() const {
42154213 return matched ? string_type(this->first, this->second) : string_type();
42164214 }
42174215 _LIBCPP_HIDE_FROM_ABI operator string_type() const { return str(); }
42184216
4219 _LIBCPP_HIDE_FROM_ABI int compare(const sub_match& __s) const { return str().compare(__s.str()); }
4220 _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const { return str().compare(__s); }
4221 _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { return str().compare(__s); }
4217 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int compare(const sub_match& __s) const { return str().compare(__s.str()); }
4218 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const { return str().compare(__s); }
4219 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { return str().compare(__s); }
42224220
42234221 _LIBCPP_HIDE_FROM_ABI void swap(sub_match& __s) _NOEXCEPT_(__is_nothrow_swappable_v<_BidirectionalIterator>) {
42244222 this->pair<_BidirectionalIterator, _BidirectionalIterator>::swap(__s);
......@@ -4583,49 +4581,53 @@ public:
45834581 _LIBCPP_HIDE_FROM_ABI bool ready() const { return __ready_; }
45844582
45854583 // size:
4586 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __matches_.size(); }
4587 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __matches_.max_size(); }
4584 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __matches_.size(); }
4585 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __matches_.max_size(); }
45884586 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; }
45894587
45904588 // element access:
4591 _LIBCPP_HIDE_FROM_ABI difference_type length(size_type __sub = 0) const {
4589 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI difference_type length(size_type __sub = 0) const {
45924590 // If the match results are not ready, this will return `0`.
45934591 _LIBCPP_ASSERT_PEDANTIC(ready(), "match_results::length() called when not ready");
45944592 return (*this)[__sub].length();
45954593 }
4596 _LIBCPP_HIDE_FROM_ABI difference_type position(size_type __sub = 0) const {
4594 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI difference_type position(size_type __sub = 0) const {
45974595 // If the match results are not ready, this will return the result of subtracting two default-constructed iterators
45984596 // (which is typically a well-defined operation).
45994597 _LIBCPP_ASSERT_PEDANTIC(ready(), "match_results::position() called when not ready");
46004598 return std::distance(__position_start_, (*this)[__sub].first);
46014599 }
4602 _LIBCPP_HIDE_FROM_ABI string_type str(size_type __sub = 0) const {
4600 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type str(size_type __sub = 0) const {
46034601 // If the match results are not ready, this will return an empty string.
46044602 _LIBCPP_ASSERT_PEDANTIC(ready(), "match_results::str() called when not ready");
46054603 return (*this)[__sub].str();
46064604 }
4607 _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __n) const {
4605 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __n) const {
46084606 // If the match results are not ready, this call will be equivalent to calling this function with `__n >= size()`,
46094607 // returning an empty subrange.
46104608 _LIBCPP_ASSERT_PEDANTIC(ready(), "match_results::operator[]() called when not ready");
46114609 return __n < __matches_.size() ? __matches_[__n] : __unmatched_;
46124610 }
46134611
4614 _LIBCPP_HIDE_FROM_ABI const_reference prefix() const {
4612 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference prefix() const {
46154613 // If the match results are not ready, this will return a default-constructed empty `__suffix_`.
46164614 _LIBCPP_ASSERT_PEDANTIC(ready(), "match_results::prefix() called when not ready");
46174615 return __prefix_;
46184616 }
4619 _LIBCPP_HIDE_FROM_ABI const_reference suffix() const {
4617 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference suffix() const {
46204618 // If the match results are not ready, this will return a default-constructed empty `__suffix_`.
46214619 _LIBCPP_ASSERT_PEDANTIC(ready(), "match_results::suffix() called when not ready");
46224620 return __suffix_;
46234621 }
46244622
4625 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const { return empty() ? __matches_.end() : __matches_.begin(); }
4626 _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return __matches_.end(); }
4627 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const { return empty() ? __matches_.end() : __matches_.begin(); }
4628 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const { return __matches_.end(); }
4623 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const {
4624 return empty() ? __matches_.end() : __matches_.begin();
4625 }
4626 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return __matches_.end(); }
4627 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const {
4628 return empty() ? __matches_.end() : __matches_.begin();
4629 }
4630 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const { return __matches_.end(); }
46294631
46304632 // format:
46314633 template <class _OutputIter>
......@@ -4641,14 +4643,14 @@ public:
46414643 return format(__output_iter, __fmt.data(), __fmt.data() + __fmt.size(), __flags);
46424644 }
46434645 template <class _ST, class _SA>
4644 _LIBCPP_HIDE_FROM_ABI basic_string<char_type, _ST, _SA>
4646 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_string<char_type, _ST, _SA>
46454647 format(const basic_string<char_type, _ST, _SA>& __fmt,
46464648 regex_constants::match_flag_type __flags = regex_constants::format_default) const {
46474649 basic_string<char_type, _ST, _SA> __r;
46484650 format(std::back_inserter(__r), __fmt.data(), __fmt.data() + __fmt.size(), __flags);
46494651 return __r;
46504652 }
4651 _LIBCPP_HIDE_FROM_ABI string_type
4653 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type
46524654 format(const char_type* __fmt, regex_constants::match_flag_type __flags = regex_constants::format_default) const {
46534655 string_type __r;
46544656 format(std::back_inserter(__r), __fmt, __fmt + char_traits<char_type>::length(__fmt), __flags);
......@@ -4656,7 +4658,7 @@ public:
46564658 }
46574659
46584660 // allocator:
4659 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const { return __matches_.get_allocator(); }
4661 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const { return __matches_.get_allocator(); }
46604662
46614663 // swap:
46624664 void swap(match_results& __m);
......@@ -5377,7 +5379,7 @@ public:
53775379 _LIBCPP_HIDE_FROM_ABI bool operator!=(const regex_iterator& __x) const { return !(*this == __x); }
53785380# endif
53795381
5380 _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __match_; }
5382 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __match_; }
53815383 _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return std::addressof(__match_); }
53825384
53835385 regex_iterator& operator++();
......@@ -5558,7 +5560,7 @@ public:
55585560 _LIBCPP_HIDE_FROM_ABI bool operator!=(const regex_token_iterator& __x) const { return !(*this == __x); }
55595561# endif
55605562
5561 _LIBCPP_HIDE_FROM_ABI const value_type& operator*() const { return *__result_; }
5563 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const value_type& operator*() const { return *__result_; }
55625564 _LIBCPP_HIDE_FROM_ABI const value_type* operator->() const { return __result_; }
55635565
55645566 regex_token_iterator& operator++();
lib/libcxx/include/scoped_allocator+16-11
......@@ -382,13 +382,17 @@ public:
382382 // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
383383 // ~scoped_allocator_adaptor() = default;
384384
385 _LIBCPP_HIDE_FROM_ABI inner_allocator_type& inner_allocator() _NOEXCEPT { return _Base::inner_allocator(); }
386 _LIBCPP_HIDE_FROM_ABI const inner_allocator_type& inner_allocator() const _NOEXCEPT {
385 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inner_allocator_type& inner_allocator() _NOEXCEPT {
386 return _Base::inner_allocator();
387 }
388 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const inner_allocator_type& inner_allocator() const _NOEXCEPT {
387389 return _Base::inner_allocator();
388390 }
389391
390 _LIBCPP_HIDE_FROM_ABI outer_allocator_type& outer_allocator() _NOEXCEPT { return _Base::outer_allocator(); }
391 _LIBCPP_HIDE_FROM_ABI const outer_allocator_type& outer_allocator() const _NOEXCEPT {
392 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI outer_allocator_type& outer_allocator() _NOEXCEPT {
393 return _Base::outer_allocator();
394 }
395 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const outer_allocator_type& outer_allocator() const _NOEXCEPT {
392396 return _Base::outer_allocator();
393397 }
394398
......@@ -403,7 +407,7 @@ public:
403407 allocator_traits<outer_allocator_type>::deallocate(outer_allocator(), __p, __n);
404408 }
405409
406 _LIBCPP_HIDE_FROM_ABI size_type max_size() const {
410 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const {
407411 return allocator_traits<outer_allocator_type>::max_size(outer_allocator());
408412 }
409413
......@@ -434,10 +438,10 @@ public:
434438 piecewise_construct,
435439 __transform_tuple(typename __uses_alloc_ctor< _T1, inner_allocator_type&, _Args1... >::type(),
436440 std::move(__x),
437 typename __make_tuple_indices<sizeof...(_Args1)>::type{}),
441 __index_sequence_for<_Args1...>()),
438442 __transform_tuple(typename __uses_alloc_ctor< _T2, inner_allocator_type&, _Args2... >::type(),
439443 std::move(__y),
440 typename __make_tuple_indices<sizeof...(_Args2)>::type{}));
444 __index_sequence_for<_Args2...>()));
441445 }
442446
443447 template <class _T1, class _T2>
......@@ -473,7 +477,8 @@ public:
473477 allocator_traits<typename _OM::type>::destroy(_OM()(outer_allocator()), __p);
474478 }
475479
476 _LIBCPP_HIDE_FROM_ABI scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT {
480 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI scoped_allocator_adaptor
481 select_on_container_copy_construction() const _NOEXCEPT {
477482 return _Base::select_on_container_copy_construction();
478483 }
479484
......@@ -503,20 +508,20 @@ private:
503508
504509 template <class... _Args, size_t... _Idx>
505510 _LIBCPP_HIDE_FROM_ABI tuple<_Args&&...>
506 __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, __tuple_indices<_Idx...>) {
511 __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, __index_sequence<_Idx...>) {
507512 return std::forward_as_tuple(std::get<_Idx>(std::move(__t))...);
508513 }
509514
510515 template <class... _Args, size_t... _Idx>
511516 _LIBCPP_HIDE_FROM_ABI tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>
512 __transform_tuple(integral_constant<int, 1>, tuple<_Args...>&& __t, __tuple_indices<_Idx...>) {
517 __transform_tuple(integral_constant<int, 1>, tuple<_Args...>&& __t, __index_sequence<_Idx...>) {
513518 using _Tup = tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>;
514519 return _Tup(allocator_arg, inner_allocator(), std::get<_Idx>(std::move(__t))...);
515520 }
516521
517522 template <class... _Args, size_t... _Idx>
518523 _LIBCPP_HIDE_FROM_ABI tuple<_Args&&..., inner_allocator_type&>
519 __transform_tuple(integral_constant<int, 2>, tuple<_Args...>&& __t, __tuple_indices<_Idx...>) {
524 __transform_tuple(integral_constant<int, 2>, tuple<_Args...>&& __t, __index_sequence<_Idx...>) {
520525 using _Tup = tuple<_Args&&..., inner_allocator_type&>;
521526 return _Tup(std::get<_Idx>(std::move(__t))..., inner_allocator());
522527 }
lib/libcxx/include/semaphore+15-18
......@@ -55,12 +55,11 @@ using binary_semaphore = counting_semaphore<1>; // since C++20
5555# include <__assert>
5656# include <__atomic/atomic.h>
5757# include <__atomic/atomic_sync.h>
58# include <__atomic/atomic_sync_timed.h>
5859# include <__atomic/memory_order.h>
5960# include <__chrono/time_point.h>
6061# include <__cstddef/ptrdiff_t.h>
61# include <__thread/poll_with_backoff.h>
6262# include <__thread/support.h>
63# include <__thread/timed_backoff_policy.h>
6463# include <limits>
6564# include <version>
6665
......@@ -90,7 +89,7 @@ class __atomic_semaphore_base {
9089
9190public:
9291 _LIBCPP_HIDE_FROM_ABI constexpr explicit __atomic_semaphore_base(ptrdiff_t __count) : __a_(__count) {}
93 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void release(ptrdiff_t __update = 1) {
92 _LIBCPP_HIDE_FROM_ABI void release(ptrdiff_t __update = 1) {
9493 auto __old = __a_.fetch_add(__update, memory_order_release);
9594 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
9695 __update <= _LIBCPP_SEMAPHORE_MAX - __old, "update is greater than the expected value");
......@@ -98,26 +97,26 @@ public:
9897 __a_.notify_all();
9998 }
10099 }
101 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void acquire() {
100 _LIBCPP_HIDE_FROM_ABI void acquire() {
102101 std::__atomic_wait_unless(__a_, memory_order_relaxed, [this](ptrdiff_t& __old) {
103102 return __try_acquire_impl(__old);
104103 });
105104 }
106105 template <class _Rep, class _Period>
107 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool
108 try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) {
106 _LIBCPP_HIDE_FROM_ABI bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) {
109107 if (__rel_time == chrono::duration<_Rep, _Period>::zero())
110108 return try_acquire();
111 auto const __poll_fn = [this]() { return try_acquire(); };
112 return std::__libcpp_thread_poll_with_backoff(__poll_fn, __libcpp_timed_backoff_policy(), __rel_time);
109
110 return std::__atomic_wait_unless_with_timeout(
111 __a_, memory_order_relaxed, [this](ptrdiff_t& __old) { return __try_acquire_impl(__old); }, __rel_time);
113112 }
114 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool try_acquire() {
113 _LIBCPP_HIDE_FROM_ABI bool try_acquire() {
115114 auto __old = __a_.load(memory_order_relaxed);
116115 return __try_acquire_impl(__old);
117116 }
118117
119118private:
120 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __try_acquire_impl(ptrdiff_t& __old) {
119 _LIBCPP_HIDE_FROM_ABI bool __try_acquire_impl(ptrdiff_t& __old) {
121120 while (true) {
122121 if (__old == 0)
123122 return false;
......@@ -134,7 +133,7 @@ class counting_semaphore {
134133public:
135134 static_assert(__least_max_value >= 0, "The least maximum value must be a positive number");
136135
137 static constexpr ptrdiff_t max() noexcept { return __least_max_value; }
136 [[nodiscard]] static constexpr ptrdiff_t max() noexcept { return __least_max_value; }
138137
139138 _LIBCPP_HIDE_FROM_ABI constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore_(__count) {
140139 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
......@@ -151,20 +150,18 @@ public:
151150 counting_semaphore(const counting_semaphore&) = delete;
152151 counting_semaphore& operator=(const counting_semaphore&) = delete;
153152
154 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void release(ptrdiff_t __update = 1) {
153 _LIBCPP_HIDE_FROM_ABI void release(ptrdiff_t __update = 1) {
155154 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__update >= 0, "counting_semaphore:release called with a negative value");
156155 __semaphore_.release(__update);
157156 }
158 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void acquire() { __semaphore_.acquire(); }
157 _LIBCPP_HIDE_FROM_ABI void acquire() { __semaphore_.acquire(); }
159158 template <class _Rep, class _Period>
160 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool
161 try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) {
159 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) {
162160 return __semaphore_.try_acquire_for(chrono::duration_cast<chrono::nanoseconds>(__rel_time));
163161 }
164 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool try_acquire() { return __semaphore_.try_acquire(); }
162 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool try_acquire() { return __semaphore_.try_acquire(); }
165163 template <class _Clock, class _Duration>
166 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool
167 try_acquire_until(chrono::time_point<_Clock, _Duration> const& __abs_time) {
164 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool try_acquire_until(chrono::time_point<_Clock, _Duration> const& __abs_time) {
168165 auto const __current = _Clock::now();
169166 if (__current >= __abs_time)
170167 return try_acquire();
lib/libcxx/include/set+220-192
......@@ -518,19 +518,19 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
518518# include <__algorithm/equal.h>
519519# include <__algorithm/lexicographical_compare.h>
520520# include <__algorithm/lexicographical_compare_three_way.h>
521# include <__algorithm/specialized_algorithms.h>
521522# include <__assert>
522523# include <__config>
523524# include <__functional/is_transparent.h>
524525# include <__functional/operations.h>
525# include <__fwd/set.h>
526526# include <__iterator/erase_if_container.h>
527527# include <__iterator/iterator_traits.h>
528# include <__iterator/ranges_iterator_traits.h>
529528# include <__iterator/reverse_iterator.h>
530529# include <__memory/allocator.h>
531530# include <__memory/allocator_traits.h>
532531# include <__memory_resource/polymorphic_allocator.h>
533532# include <__node_handle>
533# include <__ranges/access.h>
534534# include <__ranges/concepts.h>
535535# include <__ranges/container_compatible_range.h>
536536# include <__ranges/from_range.h>
......@@ -538,7 +538,6 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
538538# include <__type_traits/container_traits.h>
539539# include <__type_traits/enable_if.h>
540540# include <__type_traits/is_allocator.h>
541# include <__type_traits/is_nothrow_assignable.h>
542541# include <__type_traits/is_nothrow_constructible.h>
543542# include <__type_traits/is_same.h>
544543# include <__type_traits/is_swappable.h>
......@@ -570,7 +569,10 @@ _LIBCPP_PUSH_MACROS
570569
571570_LIBCPP_BEGIN_NAMESPACE_STD
572571
573template <class _Key, class _Compare, class _Allocator>
572template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> >
573class multiset;
574
575template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> >
574576class set {
575577public:
576578 // types:
......@@ -660,22 +662,20 @@ public:
660662 : set(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
661663# endif
662664
663 _LIBCPP_HIDE_FROM_ABI set(const set& __s) : __tree_(__s.__tree_) { insert(__s.begin(), __s.end()); }
665 _LIBCPP_HIDE_FROM_ABI set(const set& __s) = default;
664666
665667 _LIBCPP_HIDE_FROM_ABI set& operator=(const set& __s) = default;
666668
667669# ifndef _LIBCPP_CXX03_LANG
668 _LIBCPP_HIDE_FROM_ABI set(set&& __s) noexcept(is_nothrow_move_constructible<__base>::value) = default;
670 _LIBCPP_HIDE_FROM_ABI set(set&& __s) = default;
669671# endif // _LIBCPP_CXX03_LANG
670672
671673 _LIBCPP_HIDE_FROM_ABI explicit set(const allocator_type& __a) : __tree_(__a) {}
672674
673 _LIBCPP_HIDE_FROM_ABI set(const set& __s, const allocator_type& __a) : __tree_(__s.__tree_.value_comp(), __a) {
674 insert(__s.begin(), __s.end());
675 }
675 _LIBCPP_HIDE_FROM_ABI set(const set& __s, const allocator_type& __alloc) : __tree_(__s.__tree_, __alloc) {}
676676
677677# ifndef _LIBCPP_CXX03_LANG
678 _LIBCPP_HIDE_FROM_ABI set(set&& __s, const allocator_type& __a);
678 _LIBCPP_HIDE_FROM_ABI set(set&& __s, const allocator_type& __alloc) : __tree_(std::move(__s.__tree_), __alloc) {}
679679
680680 _LIBCPP_HIDE_FROM_ABI set(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
681681 : __tree_(__comp) {
......@@ -693,36 +693,38 @@ public:
693693# endif
694694
695695 _LIBCPP_HIDE_FROM_ABI set& operator=(initializer_list<value_type> __il) {
696 __tree_.__assign_unique(__il.begin(), __il.end());
696 clear();
697 insert(__il.begin(), __il.end());
697698 return *this;
698699 }
699700
700 _LIBCPP_HIDE_FROM_ABI set& operator=(set&& __s) noexcept(is_nothrow_move_assignable<__base>::value) {
701 __tree_ = std::move(__s.__tree_);
702 return *this;
703 }
701 _LIBCPP_HIDE_FROM_ABI set& operator=(set&& __s) = default;
704702# endif // _LIBCPP_CXX03_LANG
705703
706704 _LIBCPP_HIDE_FROM_ABI ~set() { static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
707705
708 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
709 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
710 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
711 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
706 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
707 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
708 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
709 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
712710
713 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
714 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
715 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
716 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
711 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
712 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
713 return const_reverse_iterator(end());
714 }
715 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
716 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
717 return const_reverse_iterator(begin());
718 }
717719
718 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
719 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
720 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
721 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
720 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
721 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
722 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
723 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
722724
723725 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
724 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
725 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
726 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
727 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
726728
727729 // modifiers:
728730# ifndef _LIBCPP_CXX03_LANG
......@@ -732,28 +734,24 @@ public:
732734 }
733735 template <class... _Args>
734736 _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {
735 return __tree_.__emplace_hint_unique(__p, std::forward<_Args>(__args)...);
737 return __tree_.__emplace_hint_unique(__p, std::forward<_Args>(__args)...).first;
736738 }
737739# endif // _LIBCPP_CXX03_LANG
738740
739741 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__emplace_unique(__v); }
740742 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
741 return __tree_.__emplace_hint_unique(__p, __v);
743 return __tree_.__emplace_hint_unique(__p, __v).first;
742744 }
743745
744746 template <class _InputIterator>
745 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
746 for (const_iterator __e = cend(); __f != __l; ++__f)
747 __tree_.__emplace_hint_unique(__e, *__f);
747 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last) {
748 __tree_.__insert_range_unique(__first, __last);
748749 }
749750
750751# if _LIBCPP_STD_VER >= 23
751752 template <_ContainerCompatibleRange<value_type> _Range>
752753 _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
753 const_iterator __end = cend();
754 for (auto&& __element : __range) {
755 __tree_.__emplace_hint_unique(__end, std::forward<decltype(__element)>(__element));
756 }
754 __tree_.__insert_range_unique(ranges::begin(__range), ranges::end(__range));
757755 }
758756# endif
759757
......@@ -763,7 +761,7 @@ public:
763761 }
764762
765763 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
766 return __tree_.__emplace_hint_unique(__p, std::move(__v));
764 return __tree_.__emplace_hint_unique(__p, std::move(__v)).first;
767765 }
768766
769767 _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
......@@ -785,10 +783,10 @@ public:
785783 "node_type with incompatible allocator passed to set::insert()");
786784 return __tree_.template __node_handle_insert_unique<node_type>(__hint, std::move(__nh));
787785 }
788 _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
786 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
789787 return __tree_.template __node_handle_extract<node_type>(__key);
790788 }
791 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
789 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
792790 return __tree_.template __node_handle_extract<node_type>(__it);
793791 }
794792 template <class _Compare2>
......@@ -819,101 +817,120 @@ public:
819817
820818 _LIBCPP_HIDE_FROM_ABI void swap(set& __s) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) { __tree_.swap(__s.__tree_); }
821819
822 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __tree_.__alloc(); }
823 _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp(); }
824 _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return __tree_.value_comp(); }
820 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __tree_.__alloc(); }
821 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp(); }
822 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return __tree_.value_comp(); }
825823
826824 // set operations:
827 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
828 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
825 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
826 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
829827# if _LIBCPP_STD_VER >= 14
830828 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
831 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
829 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
832830 return __tree_.find(__k);
833831 }
834832 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
835 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
833 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
836834 return __tree_.find(__k);
837835 }
838836# endif
839837
840 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_unique(__k); }
838 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const {
839 return __tree_.__count_unique(__k);
840 }
841841# if _LIBCPP_STD_VER >= 14
842842 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
843 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
843 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
844844 return __tree_.__count_multi(__k);
845845 }
846846# endif
847847
848848# if _LIBCPP_STD_VER >= 20
849 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
849 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
850850 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
851 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
851 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
852852 return find(__k) != end();
853853 }
854854# endif // _LIBCPP_STD_VER >= 20
855855
856 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.lower_bound(__k); }
857 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const { return __tree_.lower_bound(__k); }
856 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) {
857 return __tree_.__lower_bound_unique(__k);
858 }
859
860 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const {
861 return __tree_.__lower_bound_unique(__k);
862 }
863
864 // The transparent versions of the lookup functions use the _multi version, since a non-element key is allowed to
865 // match multiple elements.
858866# if _LIBCPP_STD_VER >= 14
859867 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
860 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
861 return __tree_.lower_bound(__k);
868 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
869 return __tree_.__lower_bound_multi(__k);
862870 }
863871
864872 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
865 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
866 return __tree_.lower_bound(__k);
873 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
874 return __tree_.__lower_bound_multi(__k);
867875 }
868876# endif
869877
870 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.upper_bound(__k); }
871 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const { return __tree_.upper_bound(__k); }
878 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) {
879 return __tree_.__upper_bound_unique(__k);
880 }
881
882 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const {
883 return __tree_.__upper_bound_unique(__k);
884 }
885
872886# if _LIBCPP_STD_VER >= 14
873887 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
874 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
875 return __tree_.upper_bound(__k);
888 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
889 return __tree_.__upper_bound_multi(__k);
876890 }
877891 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
878 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
879 return __tree_.upper_bound(__k);
892 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
893 return __tree_.__upper_bound_multi(__k);
880894 }
881895# endif
882896
883 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
897 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
884898 return __tree_.__equal_range_unique(__k);
885899 }
886 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
900 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
887901 return __tree_.__equal_range_unique(__k);
888902 }
889903# if _LIBCPP_STD_VER >= 14
890904 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
891 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
905 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
892906 return __tree_.__equal_range_multi(__k);
893907 }
894908 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
895 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
909 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
896910 return __tree_.__equal_range_multi(__k);
897911 }
898912# endif
913
914 template <class, class...>
915 friend struct __specialized_algorithm;
899916};
900917
901918# if _LIBCPP_STD_VER >= 17
902919template <class _InputIterator,
903 class _Compare = less<__iter_value_type<_InputIterator>>,
904 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
920 class _Compare = less<__iterator_value_type<_InputIterator>>,
921 class _Allocator = allocator<__iterator_value_type<_InputIterator>>,
905922 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
906 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
907 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
923 class = enable_if_t<__is_allocator_v<_Allocator>>,
924 class = enable_if_t<!__is_allocator_v<_Compare>>>
908925set(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
909 -> set<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
926 -> set<__iterator_value_type<_InputIterator>, _Compare, _Allocator>;
910927
911928# if _LIBCPP_STD_VER >= 23
912929template <ranges::input_range _Range,
913930 class _Compare = less<ranges::range_value_t<_Range>>,
914931 class _Allocator = allocator<ranges::range_value_t<_Range>>,
915 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
916 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
932 class = enable_if_t<__is_allocator_v<_Allocator>>,
933 class = enable_if_t<!__is_allocator_v<_Compare>>>
917934set(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
918935 -> set<ranges::range_value_t<_Range>, _Compare, _Allocator>;
919936# endif
......@@ -921,41 +938,43 @@ set(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
921938template <class _Key,
922939 class _Compare = less<_Key>,
923940 class _Allocator = allocator<_Key>,
924 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
925 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
941 class = enable_if_t<!__is_allocator_v<_Compare>>,
942 class = enable_if_t<__is_allocator_v<_Allocator>>>
926943set(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator()) -> set<_Key, _Compare, _Allocator>;
927944
928945template <class _InputIterator,
929946 class _Allocator,
930947 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
931 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
932set(_InputIterator,
933 _InputIterator,
934 _Allocator) -> set<__iter_value_type<_InputIterator>, less<__iter_value_type<_InputIterator>>, _Allocator>;
948 class = enable_if_t<__is_allocator_v<_Allocator>>>
949set(_InputIterator, _InputIterator, _Allocator)
950 -> set<__iterator_value_type<_InputIterator>, less<__iterator_value_type<_InputIterator>>, _Allocator>;
935951
936952# if _LIBCPP_STD_VER >= 23
937template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
938set(from_range_t,
939 _Range&&,
940 _Allocator) -> set<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
953template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
954set(from_range_t, _Range&&, _Allocator)
955 -> set<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
941956# endif
942957
943template <class _Key, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
958template <class _Key, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
944959set(initializer_list<_Key>, _Allocator) -> set<_Key, less<_Key>, _Allocator>;
945960# endif
946961
947# ifndef _LIBCPP_CXX03_LANG
962# if _LIBCPP_STD_VER >= 14
963template <class _Alg, class _Key, class _Compare, class _Allocator>
964struct __specialized_algorithm<_Alg, __single_range<set<_Key, _Compare, _Allocator>>> {
965 using __set _LIBCPP_NODEBUG = set<_Key, _Compare, _Allocator>;
948966
949template <class _Key, class _Compare, class _Allocator>
950set<_Key, _Compare, _Allocator>::set(set&& __s, const allocator_type& __a) : __tree_(std::move(__s.__tree_), __a) {
951 if (__a != __s.get_allocator()) {
952 const_iterator __e = cend();
953 while (!__s.empty())
954 insert(__e, std::move(__s.__tree_.remove(__s.begin())->__value_));
955 }
956}
967 static const bool __has_algorithm =
968 __specialized_algorithm<_Alg, __single_range<typename __set::__base>>::__has_algorithm;
957969
958# endif // _LIBCPP_CXX03_LANG
970 // set's begin() and end() are identical with and without const qualification
971 template <class... _Args>
972 _LIBCPP_HIDE_FROM_ABI static auto operator()(const __set& __set, _Args&&... __args) {
973 return __specialized_algorithm<_Alg, __single_range<typename __set::__base>>()(
974 __set.__tree_, std::forward<_Args>(__args)...);
975 }
976};
977# endif
959978
960979template <class _Key, class _Compare, class _Allocator>
961980inline _LIBCPP_HIDE_FROM_ABI bool
......@@ -1119,24 +1138,17 @@ public:
11191138 : multiset(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
11201139# endif
11211140
1122 _LIBCPP_HIDE_FROM_ABI multiset(const multiset& __s)
1123 : __tree_(__s.__tree_.value_comp(),
1124 __alloc_traits::select_on_container_copy_construction(__s.__tree_.__alloc())) {
1125 insert(__s.begin(), __s.end());
1126 }
1141 _LIBCPP_HIDE_FROM_ABI multiset(const multiset& __s) = default;
11271142
11281143 _LIBCPP_HIDE_FROM_ABI multiset& operator=(const multiset& __s) = default;
11291144
11301145# ifndef _LIBCPP_CXX03_LANG
1131 _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s) noexcept(is_nothrow_move_constructible<__base>::value) = default;
1146 _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s) = default;
11321147
1133 _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s, const allocator_type& __a);
1148 _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s, const allocator_type& __a) : __tree_(std::move(__s.__tree_), __a) {}
11341149# endif // _LIBCPP_CXX03_LANG
11351150 _LIBCPP_HIDE_FROM_ABI explicit multiset(const allocator_type& __a) : __tree_(__a) {}
1136 _LIBCPP_HIDE_FROM_ABI multiset(const multiset& __s, const allocator_type& __a)
1137 : __tree_(__s.__tree_.value_comp(), __a) {
1138 insert(__s.begin(), __s.end());
1139 }
1151 _LIBCPP_HIDE_FROM_ABI multiset(const multiset& __s, const allocator_type& __a) : __tree_(__s.__tree_, __a) {}
11401152
11411153# ifndef _LIBCPP_CXX03_LANG
11421154 _LIBCPP_HIDE_FROM_ABI multiset(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
......@@ -1156,38 +1168,40 @@ public:
11561168# endif
11571169
11581170 _LIBCPP_HIDE_FROM_ABI multiset& operator=(initializer_list<value_type> __il) {
1159 __tree_.__assign_multi(__il.begin(), __il.end());
1171 clear();
1172 insert(__il.begin(), __il.end());
11601173 return *this;
11611174 }
11621175
1163 _LIBCPP_HIDE_FROM_ABI multiset& operator=(multiset&& __s) _NOEXCEPT_(is_nothrow_move_assignable<__base>::value) {
1164 __tree_ = std::move(__s.__tree_);
1165 return *this;
1166 }
1176 _LIBCPP_HIDE_FROM_ABI multiset& operator=(multiset&& __s) = default;
11671177# endif // _LIBCPP_CXX03_LANG
11681178
11691179 _LIBCPP_HIDE_FROM_ABI ~multiset() {
11701180 static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), "");
11711181 }
11721182
1173 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
1174 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
1175 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
1176 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
1183 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
1184 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
1185 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
1186 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
11771187
1178 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
1179 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
1180 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
1181 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
1188 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
1189 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
1190 return const_reverse_iterator(end());
1191 }
1192 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
1193 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
1194 return const_reverse_iterator(begin());
1195 }
11821196
1183 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
1184 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
1185 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
1186 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
1197 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
1198 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
1199 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
1200 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
11871201
11881202 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
1189 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
1190 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
1203 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
1204 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
11911205
11921206 // modifiers:
11931207# ifndef _LIBCPP_CXX03_LANG
......@@ -1207,18 +1221,14 @@ public:
12071221 }
12081222
12091223 template <class _InputIterator>
1210 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
1211 for (const_iterator __e = cend(); __f != __l; ++__f)
1212 __tree_.__emplace_hint_multi(__e, *__f);
1224 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last) {
1225 __tree_.__insert_range_multi(__first, __last);
12131226 }
12141227
12151228# if _LIBCPP_STD_VER >= 23
12161229 template <_ContainerCompatibleRange<value_type> _Range>
12171230 _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
1218 const_iterator __end = cend();
1219 for (auto&& __element : __range) {
1220 __tree_.__emplace_hint_multi(__end, std::forward<decltype(__element)>(__element));
1221 }
1231 __tree_.__insert_range_multi(ranges::begin(__range), ranges::end(__range));
12221232 }
12231233# endif
12241234
......@@ -1248,10 +1258,10 @@ public:
12481258 "node_type with incompatible allocator passed to multiset::insert()");
12491259 return __tree_.template __node_handle_insert_multi<node_type>(__hint, std::move(__nh));
12501260 }
1251 _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
1261 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
12521262 return __tree_.template __node_handle_extract<node_type>(__key);
12531263 }
1254 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
1264 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
12551265 return __tree_.template __node_handle_extract<node_type>(__it);
12561266 }
12571267 template <class _Compare2>
......@@ -1284,101 +1294,118 @@ public:
12841294 __tree_.swap(__s.__tree_);
12851295 }
12861296
1287 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __tree_.__alloc(); }
1288 _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp(); }
1289 _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return __tree_.value_comp(); }
1297 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __tree_.__alloc(); }
1298 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp(); }
1299 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return __tree_.value_comp(); }
12901300
12911301 // set operations:
1292 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
1293 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
1302 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
1303 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
12941304# if _LIBCPP_STD_VER >= 14
12951305 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1296 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1306 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
12971307 return __tree_.find(__k);
12981308 }
12991309 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1300 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1310 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
13011311 return __tree_.find(__k);
13021312 }
13031313# endif
13041314
1305 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_multi(__k); }
1315 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const {
1316 return __tree_.__count_multi(__k);
1317 }
13061318# if _LIBCPP_STD_VER >= 14
13071319 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1308 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1320 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
13091321 return __tree_.__count_multi(__k);
13101322 }
13111323# endif
13121324
13131325# if _LIBCPP_STD_VER >= 20
1314 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1326 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
13151327 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1316 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1328 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
13171329 return find(__k) != end();
13181330 }
13191331# endif // _LIBCPP_STD_VER >= 20
13201332
1321 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.lower_bound(__k); }
1322 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const { return __tree_.lower_bound(__k); }
1333 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) {
1334 return __tree_.__lower_bound_multi(__k);
1335 }
1336
1337 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const {
1338 return __tree_.__lower_bound_multi(__k);
1339 }
1340
13231341# if _LIBCPP_STD_VER >= 14
13241342 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1325 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
1326 return __tree_.lower_bound(__k);
1343 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
1344 return __tree_.__lower_bound_multi(__k);
13271345 }
13281346
13291347 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1330 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
1331 return __tree_.lower_bound(__k);
1348 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
1349 return __tree_.__lower_bound_multi(__k);
13321350 }
13331351# endif
13341352
1335 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.upper_bound(__k); }
1336 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const { return __tree_.upper_bound(__k); }
1353 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) {
1354 return __tree_.__upper_bound_multi(__k);
1355 }
1356
1357 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const {
1358 return __tree_.__upper_bound_multi(__k);
1359 }
1360
13371361# if _LIBCPP_STD_VER >= 14
13381362 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1339 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
1340 return __tree_.upper_bound(__k);
1363 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
1364 return __tree_.__upper_bound_multi(__k);
13411365 }
13421366 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1343 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
1344 return __tree_.upper_bound(__k);
1367 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
1368 return __tree_.__upper_bound_multi(__k);
13451369 }
13461370# endif
13471371
1348 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
1372 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
13491373 return __tree_.__equal_range_multi(__k);
13501374 }
1351 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
1375 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
13521376 return __tree_.__equal_range_multi(__k);
13531377 }
13541378# if _LIBCPP_STD_VER >= 14
13551379 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1356 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
1380 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
13571381 return __tree_.__equal_range_multi(__k);
13581382 }
13591383 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1360 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
1384 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
13611385 return __tree_.__equal_range_multi(__k);
13621386 }
13631387# endif
1388
1389 template <class, class...>
1390 friend struct __specialized_algorithm;
13641391};
13651392
13661393# if _LIBCPP_STD_VER >= 17
13671394template <class _InputIterator,
1368 class _Compare = less<__iter_value_type<_InputIterator>>,
1369 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
1395 class _Compare = less<__iterator_value_type<_InputIterator>>,
1396 class _Allocator = allocator<__iterator_value_type<_InputIterator>>,
13701397 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1371 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1372 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1398 class = enable_if_t<__is_allocator_v<_Allocator>>,
1399 class = enable_if_t<!__is_allocator_v<_Compare>>>
13731400multiset(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
1374 -> multiset<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
1401 -> multiset<__iterator_value_type<_InputIterator>, _Compare, _Allocator>;
13751402
13761403# if _LIBCPP_STD_VER >= 23
13771404template <ranges::input_range _Range,
13781405 class _Compare = less<ranges::range_value_t<_Range>>,
13791406 class _Allocator = allocator<ranges::range_value_t<_Range>>,
1380 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1381 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1407 class = enable_if_t<__is_allocator_v<_Allocator>>,
1408 class = enable_if_t<!__is_allocator_v<_Compare>>>
13821409multiset(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
13831410 -> multiset<ranges::range_value_t<_Range>, _Compare, _Allocator>;
13841411# endif
......@@ -1386,43 +1413,44 @@ multiset(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator(
13861413template <class _Key,
13871414 class _Compare = less<_Key>,
13881415 class _Allocator = allocator<_Key>,
1389 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1390 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1391multiset(initializer_list<_Key>,
1392 _Compare = _Compare(),
1393 _Allocator = _Allocator()) -> multiset<_Key, _Compare, _Allocator>;
1416 class = enable_if_t<__is_allocator_v<_Allocator>>,
1417 class = enable_if_t<!__is_allocator_v<_Compare>>>
1418multiset(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator())
1419 -> multiset<_Key, _Compare, _Allocator>;
13941420
13951421template <class _InputIterator,
13961422 class _Allocator,
13971423 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1398 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1424 class = enable_if_t<__is_allocator_v<_Allocator>>>
13991425multiset(_InputIterator, _InputIterator, _Allocator)
1400 -> multiset<__iter_value_type<_InputIterator>, less<__iter_value_type<_InputIterator>>, _Allocator>;
1426 -> multiset<__iterator_value_type<_InputIterator>, less<__iterator_value_type<_InputIterator>>, _Allocator>;
14011427
14021428# if _LIBCPP_STD_VER >= 23
1403template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1404multiset(from_range_t,
1405 _Range&&,
1406 _Allocator) -> multiset<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
1429template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
1430multiset(from_range_t, _Range&&, _Allocator)
1431 -> multiset<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
14071432# endif
14081433
1409template <class _Key, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1434template <class _Key, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
14101435multiset(initializer_list<_Key>, _Allocator) -> multiset<_Key, less<_Key>, _Allocator>;
14111436# endif
14121437
1413# ifndef _LIBCPP_CXX03_LANG
1438# if _LIBCPP_STD_VER >= 14
1439template <class _Alg, class _Key, class _Compare, class _Allocator>
1440struct __specialized_algorithm<_Alg, __single_range<multiset<_Key, _Compare, _Allocator>>> {
1441 using __set _LIBCPP_NODEBUG = multiset<_Key, _Compare, _Allocator>;
14141442
1415template <class _Key, class _Compare, class _Allocator>
1416multiset<_Key, _Compare, _Allocator>::multiset(multiset&& __s, const allocator_type& __a)
1417 : __tree_(std::move(__s.__tree_), __a) {
1418 if (__a != __s.get_allocator()) {
1419 const_iterator __e = cend();
1420 while (!__s.empty())
1421 insert(__e, std::move(__s.__tree_.remove(__s.begin())->__value_));
1422 }
1423}
1443 static const bool __has_algorithm =
1444 __specialized_algorithm<_Alg, __single_range<typename __set::__base>>::__has_algorithm;
14241445
1425# endif // _LIBCPP_CXX03_LANG
1446 // set's begin() and end() are identical with and without const qualification
1447 template <class... _Args>
1448 _LIBCPP_HIDE_FROM_ABI static auto operator()(const __set& __set, _Args&&... __args) {
1449 return __specialized_algorithm<_Alg, __single_range<typename __set::__base>>()(
1450 __set.__tree_, std::forward<_Args>(__args)...);
1451 }
1452};
1453# endif
14261454
14271455template <class _Key, class _Compare, class _Allocator>
14281456inline _LIBCPP_HIDE_FROM_ABI bool
lib/libcxx/include/shared_mutex+3-8
......@@ -138,6 +138,7 @@ template <class Mutex>
138138# include <__mutex/tag_types.h>
139139# include <__mutex/unique_lock.h>
140140# include <__system_error/throw_system_error.h>
141# include <__utility/move.h>
141142# include <__utility/swap.h>
142143# include <cerrno>
143144# include <version>
......@@ -340,14 +341,8 @@ public:
340341 }
341342
342343 _LIBCPP_HIDE_FROM_ABI shared_lock& operator=(shared_lock&& __u) _NOEXCEPT {
343 if (__owns_)
344 __m_->unlock_shared();
345 __m_ = nullptr;
346 __owns_ = false;
347 __m_ = __u.__m_;
348 __owns_ = __u.__owns_;
349 __u.__m_ = nullptr;
350 __u.__owns_ = false;
344 if (this != std::addressof(__u))
345 shared_lock(std::move(__u)).swap(*this);
351346 return *this;
352347 }
353348
lib/libcxx/include/span+53-37
......@@ -310,30 +310,32 @@ public:
310310 }
311311
312312 template <size_t _Count>
313 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept {
313 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept {
314314 static_assert(_Count <= _Extent, "span<T, N>::first<Count>(): Count out of range");
315315 return span<element_type, _Count>{data(), _Count};
316316 }
317317
318318 template <size_t _Count>
319 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept {
319 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept {
320320 static_assert(_Count <= _Extent, "span<T, N>::last<Count>(): Count out of range");
321321 return span<element_type, _Count>{data() + size() - _Count, _Count};
322322 }
323323
324 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept {
324 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>
325 first(size_type __count) const noexcept {
325326 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range");
326327 return {data(), __count};
327328 }
328329
329 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept {
330 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>
331 last(size_type __count) const noexcept {
330332 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range");
331333 return {data() + size() - __count, __count};
332334 }
333335
334336 template <size_t _Offset, size_t _Count = dynamic_extent>
335 _LIBCPP_HIDE_FROM_ABI constexpr auto
336 subspan() const noexcept -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> {
337 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto subspan() const noexcept
338 -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> {
337339 static_assert(_Offset <= _Extent, "span<T, N>::subspan<Offset, Count>(): Offset out of range");
338340 static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset,
339341 "span<T, N>::subspan<Offset, Count>(): Offset + Count out of range");
......@@ -342,7 +344,7 @@ public:
342344 return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
343345 }
344346
345 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>
347 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>
346348 subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept {
347349 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range");
348350 if (__count == dynamic_extent)
......@@ -352,52 +354,58 @@ public:
352354 return {data() + __offset, __count};
353355 }
354356
355 _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; }
356 _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); }
357 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; }
358 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept {
359 return _Extent * sizeof(element_type);
360 }
357361 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return _Extent == 0; }
358362
359 _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept {
363 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept {
360364 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range");
361365 return __data_[__idx];
362366 }
363367
364368# if _LIBCPP_STD_VER >= 26
365 _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const {
369 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const {
366370 if (__index >= size())
367371 std::__throw_out_of_range("span");
368372 return __data_[__index];
369373 }
370374# endif
371375
372 _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept {
376 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept {
373377 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span");
374378 return __data_[0];
375379 }
376380
377 _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept {
381 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept {
378382 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span");
379383 return __data_[size() - 1];
380384 }
381385
382 _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; }
386 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; }
383387
384388 // [span.iter], span iterator support
385 _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept {
389 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept {
386390# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
387391 return std::__make_bounded_iter(data(), data(), data() + size());
388392# else
389393 return iterator(data());
390394# endif
391395 }
392 _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept {
396 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept {
393397# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
394398 return std::__make_bounded_iter(data() + size(), data(), data() + size());
395399# else
396400 return iterator(data() + size());
397401# endif
398402 }
399 _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
400 _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
403 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept {
404 return reverse_iterator(end());
405 }
406 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept {
407 return reverse_iterator(begin());
408 }
401409
402410 _LIBCPP_HIDE_FROM_ABI span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept {
403411 return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte*>(data()), size_bytes()};
......@@ -478,36 +486,38 @@ public:
478486 : __data_{__other.data()}, __size_{__other.size()} {}
479487
480488 template <size_t _Count>
481 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept {
489 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept {
482490 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range");
483491 return span<element_type, _Count>{data(), _Count};
484492 }
485493
486494 template <size_t _Count>
487 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept {
495 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept {
488496 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range");
489497 return span<element_type, _Count>{data() + size() - _Count, _Count};
490498 }
491499
492 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept {
500 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>
501 first(size_type __count) const noexcept {
493502 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range");
494503 return {data(), __count};
495504 }
496505
497 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept {
506 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>
507 last(size_type __count) const noexcept {
498508 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range");
499509 return {data() + size() - __count, __count};
500510 }
501511
502512 template <size_t _Offset, size_t _Count = dynamic_extent>
503 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> subspan() const noexcept {
513 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> subspan() const noexcept {
504514 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range");
505515 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset,
506516 "span<T>::subspan<Offset, Count>(): Offset + Count out of range");
507517 return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
508518 }
509519
510 constexpr span<element_type, dynamic_extent> _LIBCPP_HIDE_FROM_ABI
520 [[nodiscard]] constexpr span<element_type, dynamic_extent> _LIBCPP_HIDE_FROM_ABI
511521 subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept {
512522 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range");
513523 if (__count == dynamic_extent)
......@@ -517,52 +527,58 @@ public:
517527 return {data() + __offset, __count};
518528 }
519529
520 _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; }
521 _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return __size_ * sizeof(element_type); }
530 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; }
531 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept {
532 return __size_ * sizeof(element_type);
533 }
522534 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return __size_ == 0; }
523535
524 _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept {
536 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept {
525537 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range");
526538 return __data_[__idx];
527539 }
528540
529541# if _LIBCPP_STD_VER >= 26
530 _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const {
542 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const {
531543 if (__index >= size())
532544 std::__throw_out_of_range("span");
533545 return __data_[__index];
534546 }
535547# endif
536548
537 _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept {
549 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept {
538550 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span");
539551 return __data_[0];
540552 }
541553
542 _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept {
554 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept {
543555 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span");
544556 return __data_[size() - 1];
545557 }
546558
547 _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; }
559 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; }
548560
549561 // [span.iter], span iterator support
550 _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept {
562 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept {
551563# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
552564 return std::__make_bounded_iter(data(), data(), data() + size());
553565# else
554566 return iterator(data());
555567# endif
556568 }
557 _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept {
569 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept {
558570# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
559571 return std::__make_bounded_iter(data() + size(), data(), data() + size());
560572# else
561573 return iterator(data() + size());
562574# endif
563575 }
564 _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
565 _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
576 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept {
577 return reverse_iterator(end());
578 }
579 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept {
580 return reverse_iterator(begin());
581 }
566582
567583 _LIBCPP_HIDE_FROM_ABI span<const byte, dynamic_extent> __as_bytes() const noexcept {
568584 return {reinterpret_cast<const byte*>(data()), size_bytes()};
......@@ -585,13 +601,13 @@ inline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true;
585601
586602// as_bytes & as_writable_bytes
587603template <class _Tp, size_t _Extent>
588_LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept {
604[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept {
589605 return __s.__as_bytes();
590606}
591607
592608template <class _Tp, size_t _Extent>
593609 requires(!is_const_v<_Tp>)
594_LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept {
610[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept {
595611 return __s.__as_writable_bytes();
596612}
597613
lib/libcxx/include/sstream+34-28
......@@ -461,15 +461,15 @@ public:
461461 // [stringbuf.members] Member functions:
462462
463463# if _LIBCPP_STD_VER >= 20
464 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
464 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
465465# endif
466466
467467# if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
468 string_type str() const;
468 [[__nodiscard__]] string_type str() const;
469469# else
470 _LIBCPP_HIDE_FROM_ABI string_type str() const& { return str(__str_.get_allocator()); }
470 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() const& { return str(__str_.get_allocator()); }
471471
472 _LIBCPP_HIDE_FROM_ABI string_type str() && {
472 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() && {
473473 const basic_string_view<_CharT, _Traits> __view = view();
474474 typename string_type::size_type __pos = __view.empty() ? 0 : __view.data() - __str_.data();
475475 // In C++23, this is just string_type(std::move(__str_), __pos, __view.size(), __str_.get_allocator());
......@@ -484,12 +484,12 @@ public:
484484
485485# if _LIBCPP_STD_VER >= 20
486486 template <class _SAlloc>
487 requires __is_allocator<_SAlloc>::value
488 _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
487 requires __is_allocator_v<_SAlloc>
488 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
489489 return basic_string<_CharT, _Traits, _SAlloc>(view(), __sa);
490490 }
491491
492 _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept;
492 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept;
493493# endif // _LIBCPP_STD_VER >= 20
494494
495495 void str(const string_type& __s) {
......@@ -949,26 +949,28 @@ public:
949949 }
950950
951951 // [istringstream.members] Member functions:
952 _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
952 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
953953 return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(std::addressof(__sb_));
954954 }
955955
956956# if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
957 _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
957 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
958958# else
959 _LIBCPP_HIDE_FROM_ABI string_type str() const& { return __sb_.str(); }
959 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() const& { return __sb_.str(); }
960960
961 _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
961 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
962962# endif
963963
964964# if _LIBCPP_STD_VER >= 20
965965 template <class _SAlloc>
966 requires __is_allocator<_SAlloc>::value
967 _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
966 requires __is_allocator_v<_SAlloc>
967 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
968968 return __sb_.str(__sa);
969969 }
970970
971 _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
971 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept {
972 return __sb_.view();
973 }
972974# endif // _LIBCPP_STD_VER >= 20
973975
974976 _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
......@@ -1087,26 +1089,28 @@ public:
10871089 }
10881090
10891091 // [ostringstream.members] Member functions:
1090 _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
1092 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
10911093 return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(std::addressof(__sb_));
10921094 }
10931095
10941096# if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
1095 _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
1097 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
10961098# else
1097 _LIBCPP_HIDE_FROM_ABI string_type str() const& { return __sb_.str(); }
1099 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() const& { return __sb_.str(); }
10981100
1099 _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
1101 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
11001102# endif
11011103
11021104# if _LIBCPP_STD_VER >= 20
11031105 template <class _SAlloc>
1104 requires __is_allocator<_SAlloc>::value
1105 _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
1106 requires __is_allocator_v<_SAlloc>
1107 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
11061108 return __sb_.str(__sa);
11071109 }
11081110
1109 _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
1111 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept {
1112 return __sb_.view();
1113 }
11101114# endif // _LIBCPP_STD_VER >= 20
11111115
11121116 _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
......@@ -1227,26 +1231,28 @@ public:
12271231 }
12281232
12291233 // [stringstream.members] Member functions:
1230 _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
1234 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
12311235 return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(std::addressof(__sb_));
12321236 }
12331237
12341238# if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
1235 _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
1239 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
12361240# else
1237 _LIBCPP_HIDE_FROM_ABI string_type str() const& { return __sb_.str(); }
1241 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() const& { return __sb_.str(); }
12381242
1239 _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
1243 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
12401244# endif
12411245
12421246# if _LIBCPP_STD_VER >= 20
12431247 template <class _SAlloc>
1244 requires __is_allocator<_SAlloc>::value
1245 _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
1248 requires __is_allocator_v<_SAlloc>
1249 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
12461250 return __sb_.str(__sa);
12471251 }
12481252
1249 _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
1253 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept {
1254 return __sb_.view();
1255 }
12501256# endif // _LIBCPP_STD_VER >= 20
12511257
12521258 _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
lib/libcxx/include/stack+13-15
......@@ -235,9 +235,9 @@ public:
235235# endif
236236
237237 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const { return c.empty(); }
238 _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); }
239 _LIBCPP_HIDE_FROM_ABI reference top() { return c.back(); }
240 _LIBCPP_HIDE_FROM_ABI const_reference top() const { return c.back(); }
238 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); }
239 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference top() { return c.back(); }
240 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference top() const { return c.back(); }
241241
242242 _LIBCPP_HIDE_FROM_ABI void push(const value_type& __v) { c.push_back(__v); }
243243# ifndef _LIBCPP_CXX03_LANG
......@@ -294,19 +294,19 @@ public:
294294};
295295
296296# if _LIBCPP_STD_VER >= 17
297template <class _Container, class = enable_if_t<!__is_allocator<_Container>::value> >
297template <class _Container, class = enable_if_t<!__is_allocator_v<_Container>>>
298298stack(_Container) -> stack<typename _Container::value_type, _Container>;
299299
300300template <class _Container,
301301 class _Alloc,
302 class = enable_if_t<!__is_allocator<_Container>::value>,
302 class = enable_if_t<!__is_allocator_v<_Container>>,
303303 class = enable_if_t<uses_allocator<_Container, _Alloc>::value> >
304304stack(_Container, _Alloc) -> stack<typename _Container::value_type, _Container>;
305305# endif
306306
307307# if _LIBCPP_STD_VER >= 23
308308template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
309stack(_InputIterator, _InputIterator) -> stack<__iter_value_type<_InputIterator>>;
309stack(_InputIterator, _InputIterator) -> stack<__iterator_value_type<_InputIterator>>;
310310
311311template <ranges::input_range _Range>
312312stack(from_range_t, _Range&&) -> stack<ranges::range_value_t<_Range>>;
......@@ -314,15 +314,13 @@ stack(from_range_t, _Range&&) -> stack<ranges::range_value_t<_Range>>;
314314template <class _InputIterator,
315315 class _Alloc,
316316 __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0,
317 __enable_if_t<__is_allocator<_Alloc>::value, int> = 0>
318stack(_InputIterator,
319 _InputIterator,
320 _Alloc) -> stack<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>;
321
322template <ranges::input_range _Range, class _Alloc, __enable_if_t<__is_allocator<_Alloc>::value, int> = 0>
323stack(from_range_t,
324 _Range&&,
325 _Alloc) -> stack<ranges::range_value_t<_Range>, deque<ranges::range_value_t<_Range>, _Alloc>>;
317 __enable_if_t<__is_allocator_v<_Alloc>, int> = 0>
318stack(_InputIterator, _InputIterator, _Alloc)
319 -> stack<__iterator_value_type<_InputIterator>, deque<__iterator_value_type<_InputIterator>, _Alloc>>;
320
321template <ranges::input_range _Range, class _Alloc, __enable_if_t<__is_allocator_v<_Alloc>, int> = 0>
322stack(from_range_t, _Range&&, _Alloc)
323 -> stack<ranges::range_value_t<_Range>, deque<ranges::range_value_t<_Range>, _Alloc>>;
326324
327325# endif
328326
lib/libcxx/include/stddef.h+10-10
......@@ -25,24 +25,24 @@ Types:
2525*/
2626
2727#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
28# include <__cxx03/stddef.h>
28# include <__cxx03/__config>
2929#else
3030# include <__config>
31#endif
3132
32# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
33# pragma GCC system_header
34# endif
33#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
34# pragma GCC system_header
35#endif
3536
3637// Note: This include is outside of header guards because we sometimes get included multiple times
3738// with different defines and the underlying <stddef.h> will know how to deal with that.
38# include_next <stddef.h>
39#include_next <stddef.h>
3940
40# ifndef _LIBCPP_STDDEF_H
41# define _LIBCPP_STDDEF_H
41#ifndef _LIBCPP_STDDEF_H
42# define _LIBCPP_STDDEF_H
4243
43# ifdef __cplusplus
44# ifdef __cplusplus
4445typedef decltype(nullptr) nullptr_t;
45# endif
46# endif // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
46# endif
4747
4848#endif // _LIBCPP_STDDEF_H
lib/libcxx/include/stdexcept+2-2
......@@ -91,7 +91,7 @@ public:
9191
9292 ~logic_error() _NOEXCEPT override;
9393
94 const char* what() const _NOEXCEPT override;
94 [[__nodiscard__]] const char* what() const _NOEXCEPT override;
9595# else
9696
9797public:
......@@ -115,7 +115,7 @@ public:
115115
116116 ~runtime_error() _NOEXCEPT override;
117117
118 const char* what() const _NOEXCEPT override;
118 [[__nodiscard__]] const char* what() const _NOEXCEPT override;
119119# else
120120
121121public:
lib/libcxx/include/stdio.h+20-21
......@@ -88,35 +88,34 @@ void perror(const char* s);
8888*/
8989
9090#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
91# include <__cxx03/stdio.h>
91# include <__cxx03/__config>
9292#else
9393# include <__config>
94#endif
9495
95# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
96# pragma GCC system_header
97# endif
96#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
97# pragma GCC system_header
98#endif
9899
99100// The inclusion of the system's <stdio.h> is intentionally done once outside of any include
100101// guards because some code expects to be able to include the underlying system header multiple
101102// times to get different definitions based on the macros that are set before inclusion.
102# if __has_include_next(<stdio.h>)
103# include_next <stdio.h>
104# endif
103#if __has_include_next(<stdio.h>)
104# include_next <stdio.h>
105#endif
105106
106# ifndef _LIBCPP_STDIO_H
107# define _LIBCPP_STDIO_H
107#ifndef _LIBCPP_STDIO_H
108# define _LIBCPP_STDIO_H
108109
109# ifdef __cplusplus
110# ifdef __cplusplus
110111
111# undef getc
112# undef putc
113# undef clearerr
114# undef feof
115# undef ferror
116# undef putchar
117# undef getchar
112# undef getc
113# undef putc
114# undef clearerr
115# undef feof
116# undef ferror
117# undef putchar
118# undef getchar
118119
119# endif // __cplusplus
120# endif // _LIBCPP_STDIO_H
121
122#endif // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
120# endif // __cplusplus
121#endif // _LIBCPP_STDIO_H
lib/libcxx/include/streambuf+59-19
......@@ -119,6 +119,7 @@ protected:
119119# include <__locale>
120120# include <__type_traits/is_same.h>
121121# include <__utility/is_valid_range.h>
122# include <__utility/scope_guard.h>
122123# include <climits>
123124# include <ios>
124125# include <iosfwd>
......@@ -149,47 +150,56 @@ public:
149150 virtual ~basic_streambuf() {}
150151
151152 // 27.6.2.2.1 locales:
152 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 locale pubimbue(const locale& __loc) {
153 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 locale pubimbue(const locale& __loc) {
153154 imbue(__loc);
154155 locale __r = __loc_;
155156 __loc_ = __loc;
156157 return __r;
157158 }
158159
159 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 locale getloc() const { return __loc_; }
160 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 locale getloc() const { return __loc_; }
160161
161162 // 27.6.2.2.2 buffer and positioning:
162 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_streambuf* pubsetbuf(char_type* __s, streamsize __n) {
163 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_streambuf* pubsetbuf(char_type* __s, streamsize __n) {
163164 return setbuf(__s, __n);
164165 }
165166
166 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type
167 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 pos_type
167168 pubseekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which = ios_base::in | ios_base::out) {
168169 return seekoff(__off, __way, __which);
169170 }
170171
171 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type
172 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 pos_type
172173 pubseekpos(pos_type __sp, ios_base::openmode __which = ios_base::in | ios_base::out) {
173174 return seekpos(__sp, __which);
174175 }
175176
176 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int pubsync() { return sync(); }
177 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int pubsync() { return sync(); }
177178
178179 // Get and put areas:
179180 // 27.6.2.2.3 Get area:
180 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize in_avail() {
181 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 streamsize in_avail() {
182 __check_invariants();
183 auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
184
181185 if (gptr() < egptr())
182186 return static_cast<streamsize>(egptr() - gptr());
183187 return showmanyc();
184188 }
185189
186 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type snextc() {
190 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int_type snextc() {
191 __check_invariants();
192 auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
193
187194 if (sbumpc() == traits_type::eof())
188195 return traits_type::eof();
189196 return sgetc();
190197 }
191198
192 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sbumpc() {
199 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int_type sbumpc() {
200 __check_invariants();
201 auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
202
193203 if (gptr() == egptr())
194204 return uflow();
195205 int_type __c = traits_type::to_int_type(*gptr());
......@@ -197,23 +207,32 @@ public:
197207 return __c;
198208 }
199209
200 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sgetc() {
210 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int_type sgetc() {
211 __check_invariants();
212 auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
213
201214 if (gptr() == egptr())
202215 return underflow();
203216 return traits_type::to_int_type(*gptr());
204217 }
205218
206 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize sgetn(char_type* __s, streamsize __n) { return xsgetn(__s, __n); }
219 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 streamsize sgetn(char_type* __s, streamsize __n) { return xsgetn(__s, __n); }
207220
208221 // 27.6.2.2.4 Putback:
209 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sputbackc(char_type __c) {
222 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int_type sputbackc(char_type __c) {
223 __check_invariants();
224 auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
225
210226 if (eback() == gptr() || !traits_type::eq(__c, *(gptr() - 1)))
211227 return pbackfail(traits_type::to_int_type(__c));
212228 this->gbump(-1);
213229 return traits_type::to_int_type(*gptr());
214230 }
215231
216 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sungetc() {
232 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int_type sungetc() {
233 __check_invariants();
234 auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
235
217236 if (eback() == gptr())
218237 return pbackfail();
219238 this->gbump(-1);
......@@ -221,7 +240,10 @@ public:
221240 }
222241
223242 // 27.6.2.2.5 Put area:
224 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sputc(char_type __c) {
243 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int_type sputc(char_type __c) {
244 __check_invariants();
245 auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
246
225247 if (pptr() == epptr())
226248 return overflow(traits_type::to_int_type(__c));
227249 *pptr() = __c;
......@@ -229,7 +251,7 @@ public:
229251 return traits_type::to_int_type(__c);
230252 }
231253
232 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize sputn(const char_type* __s, streamsize __n) {
254 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 streamsize sputn(const char_type* __s, streamsize __n) {
233255 return xsputn(__s, __n);
234256 }
235257
......@@ -270,12 +292,12 @@ protected:
270292 _LIBCPP_HIDE_FROM_ABI char_type* gptr() const { return __ninp_; }
271293 _LIBCPP_HIDE_FROM_ABI char_type* egptr() const { return __einp_; }
272294
273 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void gbump(int __n) { __ninp_ += __n; }
295 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void gbump(int __n) { __ninp_ += __n; }
274296
275297 // gbump takes an int, so it might not be able to represent the offset we want to add.
276298 _LIBCPP_HIDE_FROM_ABI void __gbump_ptrdiff(ptrdiff_t __n) { __ninp_ += __n; }
277299
278 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) {
300 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) {
279301 _LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__gbeg, __gnext), "[gbeg, gnext) must be a valid range");
280302 _LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__gbeg, __gend), "[gbeg, gend) must be a valid range");
281303 _LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__gnext, __gend), "[gnext, gend) must be a valid range");
......@@ -289,11 +311,11 @@ protected:
289311 _LIBCPP_HIDE_FROM_ABI char_type* pptr() const { return __nout_; }
290312 _LIBCPP_HIDE_FROM_ABI char_type* epptr() const { return __eout_; }
291313
292 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void pbump(int __n) { __nout_ += __n; }
314 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void pbump(int __n) { __nout_ += __n; }
293315
294316 _LIBCPP_HIDE_FROM_ABI void __pbump(streamsize __n) { __nout_ += __n; }
295317
296 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void setp(char_type* __pbeg, char_type* __pend) {
318 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void setp(char_type* __pbeg, char_type* __pend) {
297319 _LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__pbeg, __pend), "[pbeg, pend) must be a valid range");
298320 __bout_ = __nout_ = __pbeg;
299321 __eout_ = __pend;
......@@ -317,6 +339,9 @@ protected:
317339 virtual streamsize showmanyc() { return 0; }
318340
319341 virtual streamsize xsgetn(char_type* __s, streamsize __n) {
342 __check_invariants();
343 auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
344
320345 int_type __c;
321346 streamsize __i = 0;
322347 while (__i < __n) {
......@@ -338,6 +363,9 @@ protected:
338363
339364 virtual int_type underflow() { return traits_type::eof(); }
340365 virtual int_type uflow() {
366 __check_invariants();
367 auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
368
341369 if (underflow() == traits_type::eof())
342370 return traits_type::eof();
343371 int_type __c = traits_type::to_int_type(*gptr());
......@@ -350,6 +378,9 @@ protected:
350378
351379 // 27.6.2.4.5 Put area:
352380 virtual streamsize xsputn(const char_type* __s, streamsize __n) {
381 __check_invariants();
382 auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
383
353384 streamsize __i = 0;
354385 while (__i < __n) {
355386 if (pptr() >= epptr()) {
......@@ -370,6 +401,15 @@ protected:
370401
371402 virtual int_type overflow(int_type = traits_type::eof()) { return traits_type::eof(); }
372403
404 // This function checks some invariants of the class (it isn't exhaustive).
405 _LIBCPP_HIDE_FROM_ABI void __check_invariants() const {
406 _LIBCPP_ASSERT_INTERNAL(pbase() <= pptr(), "this is an invariant of the class");
407 _LIBCPP_ASSERT_INTERNAL(pptr() <= epptr(), "this is an invariant of the class");
408
409 _LIBCPP_ASSERT_INTERNAL(eback() <= gptr(), "this is an invariant of the class");
410 _LIBCPP_ASSERT_INTERNAL(gptr() <= egptr(), "this is an invariant of the class");
411 }
412
373413private:
374414 locale __loc_;
375415 char_type* __binp_ = nullptr;
lib/libcxx/include/string+574-573
......@@ -280,6 +280,8 @@ public:
280280 basic_string substr(size_type pos = 0, size_type n = npos) const; // constexpr in C++20, removed in C++23
281281 basic_string substr(size_type pos = 0, size_type n = npos) const&; // since C++23
282282 constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&; // since C++23
283 constexpr basic_string_view<charT, traits> subview(size_type pos = 0,
284 size_type n = npos) const; // since C++26
283285 void swap(basic_string& str)
284286 noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
285287 allocator_traits<allocator_type>::is_always_equal::value); // C++17, constexpr since C++20
......@@ -598,9 +600,9 @@ basic_string<char32_t> operator""s( const char32_t *str, size_t len );
598600# include <__debug_utils/sanitizers.h>
599601# include <__format/enable_insertable.h>
600602# include <__functional/hash.h>
603# include <__functional/is_transparent.h>
601604# include <__functional/unary_function.h>
602605# include <__fwd/string.h>
603# include <__ios/fpos.h>
604606# include <__iterator/bounded_iter.h>
605607# include <__iterator/distance.h>
606608# include <__iterator/iterator_traits.h>
......@@ -620,7 +622,6 @@ basic_string<char32_t> operator""s( const char32_t *str, size_t len );
620622# include <__ranges/concepts.h>
621623# include <__ranges/container_compatible_range.h>
622624# include <__ranges/from_range.h>
623# include <__ranges/size.h>
624625# include <__string/char_traits.h>
625626# include <__string/extern_template_lists.h>
626627# include <__type_traits/conditional.h>
......@@ -628,24 +629,23 @@ basic_string<char32_t> operator""s( const char32_t *str, size_t len );
628629# include <__type_traits/is_allocator.h>
629630# include <__type_traits/is_array.h>
630631# include <__type_traits/is_convertible.h>
632# include <__type_traits/is_generic_transparent_comparator.h>
631633# include <__type_traits/is_nothrow_assignable.h>
632634# include <__type_traits/is_nothrow_constructible.h>
633# include <__type_traits/is_replaceable.h>
634635# include <__type_traits/is_same.h>
635636# include <__type_traits/is_standard_layout.h>
636637# include <__type_traits/is_trivially_constructible.h>
637638# include <__type_traits/is_trivially_copyable.h>
638639# include <__type_traits/is_trivially_relocatable.h>
639640# include <__type_traits/remove_cvref.h>
640# include <__type_traits/void_t.h>
641# include <__utility/auto_cast.h>
642# include <__utility/declval.h>
641# include <__utility/default_three_way_comparator.h>
642# include <__utility/exception_guard.h>
643643# include <__utility/forward.h>
644644# include <__utility/is_pointer_in_range.h>
645645# include <__utility/move.h>
646# include <__utility/no_destroy.h>
646647# include <__utility/scope_guard.h>
647648# include <__utility/swap.h>
648# include <__utility/unreachable.h>
649649# include <climits>
650650# include <cstdio> // EOF
651651# include <cstring>
......@@ -700,18 +700,18 @@ __concatenate_strings(const _Allocator& __alloc,
700700 __type_identity_t<basic_string_view<_CharT, _Traits> > __str2);
701701
702702template <class _Iter>
703struct __string_is_trivial_iterator : public false_type {};
703inline const bool __string_is_trivial_iterator_v = false;
704704
705705template <class _Tp>
706struct __string_is_trivial_iterator<_Tp*> : public is_arithmetic<_Tp> {};
706inline const bool __string_is_trivial_iterator_v<_Tp*> = is_arithmetic<_Tp>::value;
707707
708708template <class _Iter>
709struct __string_is_trivial_iterator<__wrap_iter<_Iter> > : public __string_is_trivial_iterator<_Iter> {};
709inline const bool __string_is_trivial_iterator_v<__wrap_iter<_Iter> > = __string_is_trivial_iterator_v<_Iter>;
710710
711711template <class _CharT, class _Traits, class _Tp>
712struct __can_be_converted_to_string_view
713 : public _BoolConstant< is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value &&
714 !is_convertible<const _Tp&, const _CharT*>::value > {};
712inline const bool __can_be_converted_to_string_view_v =
713 is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value &&
714 !is_convertible<const _Tp&, const _CharT*>::value;
715715
716716struct __uninitialized_size_tag {};
717717struct __init_with_sentinel_tag {};
......@@ -756,20 +756,13 @@ public:
756756 // external memory. In such cases, the destructor is responsible for unpoisoning
757757 // the memory to avoid triggering false positives.
758758 // Therefore it's crucial to ensure the destructor is called.
759 //
760 // However, it is replaceable since implementing move-assignment as a destroy + move-construct
761 // will maintain the right ASAN state.
762 using __trivially_relocatable = void;
759 using __trivially_relocatable _LIBCPP_NODEBUG = void;
763760# else
764761 using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<
765762 __libcpp_is_trivially_relocatable<allocator_type>::value && __libcpp_is_trivially_relocatable<pointer>::value,
766763 basic_string,
767764 void>;
768765# endif
769 using __replaceable _LIBCPP_NODEBUG =
770 __conditional_t<__is_replaceable_v<pointer> && __container_allocator_is_replaceable<__alloc_traits>::value,
771 basic_string,
772 void>;
773766
774767# if __has_feature(address_sanitizer) && _LIBCPP_INSTRUMENTED_WITH_ASAN
775768 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __asan_volatile_wrapper(pointer const& __ptr) const {
......@@ -819,12 +812,21 @@ public:
819812 using reverse_iterator = std::reverse_iterator<iterator>;
820813 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
821814
815 using __alloc_result _LIBCPP_NODEBUG = __allocation_result<pointer, size_type>;
816
822817private:
823818 static_assert(CHAR_BIT == 8, "This implementation assumes that one byte contains 8 bits");
824819
825820# ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
826821
827822 struct __long {
823 __long() = default;
824
825 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __long(__alloc_result __alloc, size_type __size)
826 : __data_(__alloc.ptr), __size_(__size), __cap_(__alloc.count / __endian_factor), __is_long_(true) {
827 _LIBCPP_ASSERT_INTERNAL(!__fits_in_sso(__alloc.count), "Long capacity should always be larger than the SSO");
828 }
829
828830 pointer __data_;
829831 size_type __size_;
830832 size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
......@@ -872,6 +874,13 @@ private:
872874 // some platforms bit fields have a default size rather than the actual
873875 // size used, e.g., it is 4 bytes on AIX. See D128285 for details.
874876 struct __long {
877 __long() = default;
878
879 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __long(__alloc_result __alloc, size_type __size)
880 : __is_long_(true), __cap_(__alloc.count / __endian_factor), __size_(__size), __data_(__alloc.ptr) {
881 _LIBCPP_ASSERT_INTERNAL(!__fits_in_sso(__alloc.count), "Long capacity should always be larger than the SSO");
882 }
883
875884 struct _LIBCPP_PACKED {
876885 size_type __is_long_ : 1;
877886 size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1;
......@@ -898,6 +907,11 @@ private:
898907 union __rep {
899908 __short __s;
900909 __long __l;
910
911 __rep() = default;
912 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__short __r) : __s(__r) {}
913 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__long __r) : __l(__r) {}
914 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__uninitialized_tag) {}
901915 };
902916
903917 _LIBCPP_COMPRESSED_PAIR(__rep, __rep_, allocator_type, __alloc_);
......@@ -917,20 +931,7 @@ private:
917931 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(
918932 __uninitialized_size_tag, size_type __size, const allocator_type& __a)
919933 : __alloc_(__a) {
920 if (__size > max_size())
921 this->__throw_length_error();
922 if (__fits_in_sso(__size)) {
923 __rep_ = __rep();
924 __set_short_size(__size);
925 } else {
926 auto __capacity = __recommend(__size) + 1;
927 auto __allocation = __alloc_traits::allocate(__alloc_, __capacity);
928 __begin_lifetime(__allocation, __capacity);
929 __set_long_cap(__capacity);
930 __set_long_pointer(__allocation);
931 __set_long_size(__size);
932 }
933 __annotate_new(__size);
934 __init_internal_buffer(__size);
934935 }
935936
936937 template <class _Iter, class _Sent>
......@@ -966,7 +967,7 @@ private:
966967 std::__wrap_iter<const_pointer>(__get_pointer() + size()));
967968# else
968969 return const_iterator(__p);
969# endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING
970# endif // _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING
970971 }
971972
972973public:
......@@ -1057,13 +1058,13 @@ public:
10571058 }
10581059# endif // _LIBCPP_CXX03_LANG
10591060
1060 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
1061 template <__enable_if_t<__is_allocator_v<_Allocator>, int> = 0>
10611062 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) {
10621063 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "basic_string(const char*) detected nullptr");
10631064 __init(__s, traits_type::length(__s));
10641065 }
10651066
1066 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
1067 template <__enable_if_t<__is_allocator_v<_Allocator>, int> = 0>
10671068 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10681069 basic_string(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, const _Allocator& __a)
10691070 : __alloc_(__a) {
......@@ -1075,13 +1076,15 @@ public:
10751076 basic_string(nullptr_t) = delete;
10761077# endif
10771078
1078 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n) {
1079 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n)
1080 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
10791081 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
10801082 __init(__s, __n);
10811083 }
10821084
10831085 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
10841086 basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
1087 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero")
10851088 : __alloc_(__a) {
10861089 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
10871090 __init(__s, __n);
......@@ -1110,7 +1113,7 @@ public:
11101113 }
11111114# endif
11121115
1113 template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0>
1116 template <__enable_if_t<__is_allocator_v<_Allocator>, int> = 0>
11141117 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c, const _Allocator& __a)
11151118 : __alloc_(__a) {
11161119 __init(__n, __c);
......@@ -1135,7 +1138,7 @@ public:
11351138 }
11361139
11371140 template <class _Tp,
1138 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1141 __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp> &&
11391142 !is_same<__remove_cvref_t<_Tp>, basic_string>::value,
11401143 int> = 0>
11411144 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
......@@ -1147,7 +1150,7 @@ public:
11471150 }
11481151
11491152 template <class _Tp,
1150 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1153 __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp> &&
11511154 !is_same<__remove_cvref_t<_Tp>, basic_string>::value,
11521155 int> = 0>
11531156 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const _Tp& __t) {
......@@ -1156,7 +1159,7 @@ public:
11561159 }
11571160
11581161 template <class _Tp,
1159 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1162 __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp> &&
11601163 !is_same<__remove_cvref_t<_Tp>, basic_string>::value,
11611164 int> = 0>
11621165 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const _Tp& __t, const allocator_type& __a)
......@@ -1201,11 +1204,10 @@ public:
12011204 }
12021205# endif // _LIBCPP_CXX03_LANG
12031206
1204 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() {
1205 __annotate_delete();
1206 if (__is_long())
1207 __alloc_traits::deallocate(__alloc_, __get_long_pointer(), __get_long_cap());
1208 }
1207 // TODO(boomanaiden154): Once we mark this in destructors as dead on return,
1208 // we can use a normal call to __reset_internal_buffer and remove the extra
1209 // __rep constructor.
1210 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() { __reset_internal_buffer(__rep(__uninitialized_tag())); }
12091211
12101212 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator __self_view() const _NOEXCEPT {
12111213 return __self_view(typename __self_view::__assume_valid(), data(), size());
......@@ -1215,7 +1217,7 @@ public:
12151217 operator=(const basic_string& __str);
12161218
12171219 template <class _Tp,
1218 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1220 __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp> &&
12191221 !is_same<__remove_cvref_t<_Tp>, basic_string>::value,
12201222 int> = 0>
12211223 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const _Tp& __t) {
......@@ -1243,45 +1245,55 @@ public:
12431245# endif
12441246 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(value_type __c);
12451247
1246 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() _NOEXCEPT {
1248 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() _NOEXCEPT {
12471249 return __make_iterator(__get_pointer());
12481250 }
1249 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator begin() const _NOEXCEPT {
1251 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator begin() const _NOEXCEPT {
12501252 return __make_const_iterator(__get_pointer());
12511253 }
1252 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() _NOEXCEPT {
1254 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() _NOEXCEPT {
12531255 return __make_iterator(__get_pointer() + size());
12541256 }
1255 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator end() const _NOEXCEPT {
1257 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator end() const _NOEXCEPT {
12561258 return __make_const_iterator(__get_pointer() + size());
12571259 }
12581260
1259 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rbegin() _NOEXCEPT {
1261 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rbegin() _NOEXCEPT {
12601262 return reverse_iterator(end());
12611263 }
1262 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rbegin() const _NOEXCEPT {
1264 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator
1265 rbegin() const _NOEXCEPT {
12631266 return const_reverse_iterator(end());
12641267 }
1265 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rend() _NOEXCEPT {
1268 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rend() _NOEXCEPT {
12661269 return reverse_iterator(begin());
12671270 }
1268 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rend() const _NOEXCEPT {
1271 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rend() const _NOEXCEPT {
12691272 return const_reverse_iterator(begin());
12701273 }
12711274
1272 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cbegin() const _NOEXCEPT { return begin(); }
1273 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cend() const _NOEXCEPT { return end(); }
1274 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crbegin() const _NOEXCEPT {
1275 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cbegin() const _NOEXCEPT {
1276 return begin();
1277 }
1278 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cend() const _NOEXCEPT {
1279 return end();
1280 }
1281 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator
1282 crbegin() const _NOEXCEPT {
12751283 return rbegin();
12761284 }
1277 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
1285 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT {
1286 return rend();
1287 }
12781288
1279 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT {
1289 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT {
12801290 return __is_long() ? __get_long_size() : __get_short_size();
12811291 }
1282 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type length() const _NOEXCEPT { return size(); }
1292 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type length() const _NOEXCEPT {
1293 return size();
1294 }
12831295
1284 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT {
1296 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT {
12851297 if (size_type __m = __alloc_traits::max_size(__alloc_); __m <= std::numeric_limits<size_type>::max() / 2) {
12861298 size_type __res = __m - __alignment;
12871299
......@@ -1299,7 +1311,7 @@ public:
12991311 }
13001312 }
13011313
1302 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT {
1314 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT {
13031315 return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1;
13041316 }
13051317
......@@ -1311,13 +1323,19 @@ public:
13111323# if _LIBCPP_STD_VER >= 23
13121324 template <class _Op>
13131325 _LIBCPP_HIDE_FROM_ABI constexpr void resize_and_overwrite(size_type __n, _Op __op) {
1314 __resize_default_init(__n);
1315 __erase_to_end(std::move(__op)(data(), _LIBCPP_AUTO_CAST(__n)));
1326 using __result_type = decltype(std::move(__op)(data(), auto(__n)));
1327 static_assert(__integer_like<__result_type>, "Operation return type must be integer-like");
1328 size_type __sz = size();
1329 size_type __cap = capacity();
1330 if (__n > __cap)
1331 __grow_by_without_replace(__cap, __n - __cap, __sz, __sz, 0);
1332 __annotate_delete();
1333 __set_size(__n);
1334 __annotate_new(__n);
1335 __erase_to_end(std::move(__op)(data(), auto(__n)));
13161336 }
13171337# endif
13181338
1319 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __resize_default_init(size_type __n);
1320
13211339# if _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_STRING_RESERVE)
13221340 _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); }
13231341# endif
......@@ -1328,7 +1346,8 @@ public:
13281346 return size() == 0;
13291347 }
13301348
1331 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __pos) const _NOEXCEPT {
1349 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference
1350 operator[](size_type __pos) const _NOEXCEPT {
13321351 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
13331352 if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) {
13341353 return *(__get_long_pointer() + __pos);
......@@ -1336,7 +1355,8 @@ public:
13361355 return *(data() + __pos);
13371356 }
13381357
1339 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __pos) _NOEXCEPT {
1358 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference
1359 operator[](size_type __pos) _NOEXCEPT {
13401360 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
13411361 if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) {
13421362 return *(__get_long_pointer() + __pos);
......@@ -1344,15 +1364,15 @@ public:
13441364 return *(__get_pointer() + __pos);
13451365 }
13461366
1347 _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const;
1348 _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n);
1367 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const;
1368 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n);
13491369
13501370 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const basic_string& __str) {
13511371 return append(__str);
13521372 }
13531373
13541374 template <class _Tp,
1355 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1375 __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp> &&
13561376 !is_same<__remove_cvref_t<_Tp>, basic_string >::value,
13571377 int> = 0>
13581378 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const _Tp& __t) {
......@@ -1381,7 +1401,7 @@ public:
13811401 }
13821402
13831403 template <class _Tp,
1384 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1404 __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp> &&
13851405 !is_same<__remove_cvref_t<_Tp>, basic_string>::value,
13861406 int> = 0>
13871407 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const _Tp& __t) {
......@@ -1392,7 +1412,7 @@ public:
13921412 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str, size_type __pos, size_type __n = npos);
13931413
13941414 template <class _Tp,
1395 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1415 __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp> &&
13961416 !is_same<__remove_cvref_t<_Tp>, basic_string>::value,
13971417 int> = 0>
13981418 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
......@@ -1404,12 +1424,11 @@ public:
14041424 return append(__sv.data() + __pos, std::min(__n, __sz - __pos));
14051425 }
14061426
1407 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n);
1427 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n)
1428 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero");
14081429 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
14091430 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(size_type __n, value_type __c);
14101431
1411 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __append_default_init(size_type __n);
1412
14131432 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
14141433 _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
14151434 append(_InputIterator __first, _InputIterator __last) {
......@@ -1424,20 +1443,21 @@ public:
14241443 size_type __sz = size();
14251444 size_type __cap = capacity();
14261445 size_type __n = static_cast<size_type>(std::distance(__first, __last));
1427 if (__n) {
1428 if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) {
1429 if (__cap - __sz < __n)
1430 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
1431 __annotate_increase(__n);
1432 auto __end = __copy_non_overlapping_range(__first, __last, std::__to_address(__get_pointer() + __sz));
1433 traits_type::assign(*__end, value_type());
1434 __set_size(__sz + __n);
1435 } else {
1436 const basic_string __temp(__first, __last, __alloc_);
1437 append(__temp.data(), __temp.size());
1438 }
1446 if (__n == 0)
1447 return *this;
1448
1449 if (__string_is_trivial_iterator_v<_ForwardIterator> && !__addr_in_range(*__first)) {
1450 if (__cap - __sz < __n)
1451 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
1452 __annotate_increase(__n);
1453 auto __end = __copy_non_overlapping_range(__first, __last, std::__to_address(__get_pointer() + __sz));
1454 traits_type::assign(*__end, value_type());
1455 __set_size(__sz + __n);
1456 return *this;
1457 } else {
1458 const basic_string __temp(__first, __last, __alloc_);
1459 return append(__temp.data(), __temp.size());
14391460 }
1440 return *this;
14411461 }
14421462
14431463# if _LIBCPP_STD_VER >= 23
......@@ -1457,27 +1477,27 @@ public:
14571477 _LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(value_type __c);
14581478 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back();
14591479
1460 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT {
1480 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT {
14611481 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");
14621482 return *__get_pointer();
14631483 }
14641484
1465 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT {
1485 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT {
14661486 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty");
14671487 return *data();
14681488 }
14691489
1470 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT {
1490 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT {
14711491 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");
14721492 return *(__get_pointer() + size() - 1);
14731493 }
14741494
1475 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT {
1495 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT {
14761496 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty");
14771497 return *(data() + size() - 1);
14781498 }
14791499
1480 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1500 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
14811501 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const _Tp& __t) {
14821502 __self_view __sv = __t;
14831503 return assign(__sv.data(), __sv.size());
......@@ -1519,7 +1539,7 @@ public:
15191539 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n = npos);
15201540
15211541 template <class _Tp,
1522 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1542 __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp> &&
15231543 !is_same<__remove_cvref_t<_Tp>, basic_string>::value,
15241544 int> = 0>
15251545 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
......@@ -1531,8 +1551,9 @@ public:
15311551 return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
15321552 }
15331553
1534 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n);
1535 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s);
1554 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n)
1555 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero");
1556 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
15361557 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(size_type __n, value_type __c);
15371558
15381559 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
......@@ -1545,7 +1566,7 @@ public:
15451566 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
15461567 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
15471568 assign(_ForwardIterator __first, _ForwardIterator __last) {
1548 if (__string_is_trivial_iterator<_ForwardIterator>::value) {
1569 if (__string_is_trivial_iterator_v<_ForwardIterator>) {
15491570 size_type __n = static_cast<size_type>(std::distance(__first, __last));
15501571 __assign_trivial(__first, __last, __n);
15511572 } else {
......@@ -1558,7 +1579,7 @@ public:
15581579# if _LIBCPP_STD_VER >= 23
15591580 template <_ContainerCompatibleRange<_CharT> _Range>
15601581 _LIBCPP_HIDE_FROM_ABI constexpr basic_string& assign_range(_Range&& __range) {
1561 if constexpr (__string_is_trivial_iterator<ranges::iterator_t<_Range>>::value &&
1582 if constexpr (__string_is_trivial_iterator_v<ranges::iterator_t<_Range>> &&
15621583 (ranges::forward_range<_Range> || ranges::sized_range<_Range>)) {
15631584 size_type __n = static_cast<size_type>(ranges::distance(__range));
15641585 __assign_trivial(ranges::begin(__range), ranges::end(__range), __n);
......@@ -1582,14 +1603,14 @@ public:
15821603 return insert(__pos1, __str.data(), __str.size());
15831604 }
15841605
1585 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1606 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
15861607 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos1, const _Tp& __t) {
15871608 __self_view __sv = __t;
15881609 return insert(__pos1, __sv.data(), __sv.size());
15891610 }
15901611
15911612 template <class _Tp,
1592 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1613 __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp> &&
15931614 !is_same<__remove_cvref_t<_Tp>, basic_string>::value,
15941615 int> = 0>
15951616 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
......@@ -1603,7 +1624,8 @@ public:
16031624
16041625 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
16051626 insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos);
1606 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
1627 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n)
1628 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero");
16071629 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
16081630 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c);
16091631 _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __pos, value_type __c);
......@@ -1659,7 +1681,7 @@ public:
16591681 return replace(__pos1, __n1, __str.data(), __str.size());
16601682 }
16611683
1662 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1684 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
16631685 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
16641686 replace(size_type __pos1, size_type __n1, const _Tp& __t) {
16651687 __self_view __sv = __t;
......@@ -1670,7 +1692,7 @@ public:
16701692 replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos);
16711693
16721694 template <class _Tp,
1673 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
1695 __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp> &&
16741696 !is_same<__remove_cvref_t<_Tp>, basic_string>::value,
16751697 int> = 0>
16761698 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
......@@ -1683,8 +1705,10 @@ public:
16831705 }
16841706
16851707 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1686 replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
1687 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
1708 replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
1709 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero");
1710 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
1711 replace(size_type __pos, size_type __n1, const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
16881712 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
16891713
16901714 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
......@@ -1693,7 +1717,7 @@ public:
16931717 static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __str.data(), __str.size());
16941718 }
16951719
1696 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1720 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
16971721 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
16981722 replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) {
16991723 __self_view __sv = __t;
......@@ -1741,19 +1765,24 @@ public:
17411765 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
17421766
17431767# if _LIBCPP_STD_VER <= 20
1744 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string
1745 substr(size_type __pos = 0, size_type __n = npos) const {
1768 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
1769 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string substr(size_type __pos = 0, size_type __n = npos) const {
17461770 return basic_string(*this, __pos, __n);
17471771 }
17481772# else
1749 _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) const& {
1773 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) const& {
17501774 return basic_string(*this, __pos, __n);
17511775 }
17521776
1753 _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) && {
1777 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) && {
17541778 return basic_string(std::move(*this), __pos, __n);
17551779 }
17561780# endif
1781# if _LIBCPP_STD_VER >= 26
1782 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __self_view subview(size_type __pos = 0, size_type __n = npos) const {
1783 return __self_view(*this).subview(__pos, __n);
1784 }
1785# endif
17571786
17581787 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(basic_string& __str)
17591788# if _LIBCPP_STD_VER >= 14
......@@ -1765,225 +1794,238 @@ public:
17651794 // [string.ops]
17661795 // ------------
17671796
1768 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* c_str() const _NOEXCEPT { return data(); }
1769 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* data() const _NOEXCEPT {
1797 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* c_str() const _NOEXCEPT {
1798 return data();
1799 }
1800
1801 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* data() const _NOEXCEPT {
17701802 return std::__to_address(__get_pointer());
17711803 }
17721804# if _LIBCPP_STD_VER >= 17
1773 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 value_type* data() _NOEXCEPT {
1805 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 value_type* data() _NOEXCEPT {
17741806 return std::__to_address(__get_pointer());
17751807 }
17761808# endif
17771809
1778 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT {
1810 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT {
17791811 return __alloc_;
17801812 }
17811813
17821814 // find
17831815
1784 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1816 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
17851817 find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT {
17861818 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size());
17871819 }
17881820
1789 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1790 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1821 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
1822 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
17911823 find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT {
17921824 __self_view __sv = __t;
17931825 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
17941826 }
17951827
1796 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
1828 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1829 find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
1830 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
17971831 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find(): received nullptr");
17981832 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
17991833 }
18001834
1801 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1835 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
18021836 find(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
18031837 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find(): received nullptr");
18041838 return std::__str_find<value_type, size_type, traits_type, npos>(
18051839 data(), size(), __s, __pos, traits_type::length(__s));
18061840 }
18071841
1808 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT {
1842 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT {
18091843 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
18101844 }
18111845
18121846 // rfind
18131847
1814 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1848 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
18151849 rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT {
18161850 return std::__str_rfind<value_type, size_type, traits_type, npos>(
18171851 data(), size(), __str.data(), __pos, __str.size());
18181852 }
18191853
1820 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1821 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1854 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
1855 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
18221856 rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT {
18231857 __self_view __sv = __t;
18241858 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
18251859 }
18261860
1827 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
1861 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1862 rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
1863 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
18281864 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
18291865 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
18301866 }
18311867
1832 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1868 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
18331869 rfind(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
18341870 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::rfind(): received nullptr");
18351871 return std::__str_rfind<value_type, size_type, traits_type, npos>(
18361872 data(), size(), __s, __pos, traits_type::length(__s));
18371873 }
18381874
1839 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT {
1875 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1876 rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT {
18401877 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
18411878 }
18421879
18431880 // find_first_of
18441881
1845 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1882 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
18461883 find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT {
18471884 return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
18481885 data(), size(), __str.data(), __pos, __str.size());
18491886 }
18501887
1851 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1852 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1888 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
1889 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
18531890 find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT {
18541891 __self_view __sv = __t;
18551892 return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
18561893 data(), size(), __sv.data(), __pos, __sv.size());
18571894 }
18581895
1859 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1860 find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
1896 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1897 find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
1898 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
18611899 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
18621900 return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
18631901 }
18641902
1865 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1903 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
18661904 find_first_of(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
18671905 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_of(): received nullptr");
18681906 return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
18691907 data(), size(), __s, __pos, traits_type::length(__s));
18701908 }
18711909
1872 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1910 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
18731911 find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT {
18741912 return find(__c, __pos);
18751913 }
18761914
18771915 // find_last_of
18781916
1879 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1917 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
18801918 find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT {
18811919 return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
18821920 data(), size(), __str.data(), __pos, __str.size());
18831921 }
18841922
1885 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1886 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1923 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
1924 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
18871925 find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT {
18881926 __self_view __sv = __t;
18891927 return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
18901928 data(), size(), __sv.data(), __pos, __sv.size());
18911929 }
18921930
1893 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1894 find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
1931 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1932 find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
1933 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
18951934 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
18961935 return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
18971936 }
18981937
1899 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1938 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
19001939 find_last_of(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
19011940 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_of(): received nullptr");
19021941 return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
19031942 data(), size(), __s, __pos, traits_type::length(__s));
19041943 }
19051944
1906 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1945 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
19071946 find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT {
19081947 return rfind(__c, __pos);
19091948 }
19101949
19111950 // find_first_not_of
19121951
1913 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1952 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
19141953 find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT {
19151954 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
19161955 data(), size(), __str.data(), __pos, __str.size());
19171956 }
19181957
1919 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1920 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1958 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
1959 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
19211960 find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT {
19221961 __self_view __sv = __t;
19231962 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
19241963 data(), size(), __sv.data(), __pos, __sv.size());
19251964 }
19261965
1927 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1928 find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
1966 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1967 find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
1968 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
19291969 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
19301970 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
19311971 }
19321972
1933 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1973 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
19341974 find_first_not_of(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
19351975 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_not_of(): received nullptr");
19361976 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
19371977 data(), size(), __s, __pos, traits_type::length(__s));
19381978 }
19391979
1940 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1980 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
19411981 find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT {
19421982 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
19431983 }
19441984
19451985 // find_last_not_of
19461986
1947 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1987 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
19481988 find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT {
19491989 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
19501990 data(), size(), __str.data(), __pos, __str.size());
19511991 }
19521992
1953 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1954 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1993 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
1994 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
19551995 find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT {
19561996 __self_view __sv = __t;
19571997 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
19581998 data(), size(), __sv.data(), __pos, __sv.size());
19591999 }
19602000
1961 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
1962 find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT {
2001 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
2002 find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT
2003 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
19632004 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
19642005 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
19652006 }
19662007
1967 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
2008 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
19682009 find_last_not_of(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
19692010 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_not_of(): received nullptr");
19702011 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
19712012 data(), size(), __s, __pos, traits_type::length(__s));
19722013 }
19732014
1974 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
2015 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
19752016 find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT {
19762017 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
19772018 }
19782019
19792020 // compare
19802021
1981 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const basic_string& __str) const _NOEXCEPT {
2022 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
2023 compare(const basic_string& __str) const _NOEXCEPT {
19822024 return compare(__self_view(__str));
19832025 }
19842026
1985 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
1986 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const _Tp& __t) const _NOEXCEPT {
2027 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
2028 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const _Tp& __t) const _NOEXCEPT {
19872029 __self_view __sv = __t;
19882030 size_t __lhs_sz = size();
19892031 size_t __rhs_sz = __sv.size();
......@@ -1997,73 +2039,77 @@ public:
19972039 return 0;
19982040 }
19992041
2000 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
2001 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
2042 template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0>
2043 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
20022044 compare(size_type __pos1, size_type __n1, const _Tp& __t) const {
20032045 __self_view __sv = __t;
20042046 return compare(__pos1, __n1, __sv.data(), __sv.size());
20052047 }
20062048
2007 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
2049 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
20082050 compare(size_type __pos1, size_type __n1, const basic_string& __str) const {
20092051 return compare(__pos1, __n1, __str.data(), __str.size());
20102052 }
20112053
2012 _LIBCPP_CONSTEXPR_SINCE_CXX20 int
2054 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 int
20132055 compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos) const {
20142056 return compare(__pos1, __n1, __self_view(__str), __pos2, __n2);
20152057 }
20162058
20172059 template <class _Tp,
2018 __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
2060 __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp> &&
20192061 !is_same<__remove_cvref_t<_Tp>, basic_string>::value,
20202062 int> = 0>
2021 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
2063 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
20222064 compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos) const {
20232065 __self_view __sv = __t;
20242066 return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
20252067 }
20262068
2027 _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const _NOEXCEPT {
2069 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 int
2070 compare(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const _NOEXCEPT {
20282071 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr");
20292072 return compare(0, npos, __s, traits_type::length(__s));
20302073 }
20312074
2032 _LIBCPP_CONSTEXPR_SINCE_CXX20 int
2075 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 int
20332076 compare(size_type __pos1, size_type __n1, const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
20342077 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr");
20352078 return compare(__pos1, __n1, __s, traits_type::length(__s));
20362079 }
20372080
2038 _LIBCPP_CONSTEXPR_SINCE_CXX20 int
2039 compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
2081 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 int
2082 compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const
2083 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero");
20402084
20412085 // starts_with
20422086
20432087# if _LIBCPP_STD_VER >= 20
2044 constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(__self_view __sv) const noexcept {
2088 [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(__self_view __sv) const noexcept {
20452089 return __self_view(typename __self_view::__assume_valid(), data(), size()).starts_with(__sv);
20462090 }
20472091
2048 constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept {
2092 [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept {
20492093 return !empty() && _Traits::eq(front(), __c);
20502094 }
20512095
2052 constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
2096 [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool
2097 starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
20532098 return starts_with(__self_view(__s));
20542099 }
20552100
20562101 // ends_with
20572102
2058 constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(__self_view __sv) const noexcept {
2103 [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(__self_view __sv) const noexcept {
20592104 return __self_view(typename __self_view::__assume_valid(), data(), size()).ends_with(__sv);
20602105 }
20612106
2062 constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept {
2107 [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept {
20632108 return !empty() && _Traits::eq(back(), __c);
20642109 }
20652110
2066 constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
2111 [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool
2112 ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
20672113 return ends_with(__self_view(__s));
20682114 }
20692115# endif
......@@ -2071,15 +2117,16 @@ public:
20712117 // contains
20722118
20732119# if _LIBCPP_STD_VER >= 23
2074 constexpr _LIBCPP_HIDE_FROM_ABI bool contains(__self_view __sv) const noexcept {
2120 [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(__self_view __sv) const noexcept {
20752121 return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__sv);
20762122 }
20772123
2078 constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept {
2124 [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept {
20792125 return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__c);
20802126 }
20812127
2082 constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
2128 [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool
2129 contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
20832130 return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__s);
20842131 }
20852132# endif
......@@ -2095,18 +2142,6 @@ private:
20952142 return __rep_.__s.__is_long_;
20962143 }
20972144
2098 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __begin_lifetime(pointer __begin, size_type __n) {
2099# if _LIBCPP_STD_VER >= 20
2100 if (__libcpp_is_constant_evaluated()) {
2101 for (size_type __i = 0; __i != __n; ++__i)
2102 std::construct_at(std::addressof(__begin[__i]));
2103 }
2104# else
2105 (void)__begin;
2106 (void)__n;
2107# endif // _LIBCPP_STD_VER >= 20
2108 }
2109
21102145 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) { return __sz < __min_cap; }
21112146
21122147 template <class _Iterator, class _Sentinel>
......@@ -2165,6 +2200,9 @@ private:
21652200 _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
21662201 __insert_with_size(const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n);
21672202
2203 // internal buffer accessors
2204 // -------------------------
2205
21682206 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS void
21692207 __set_short_size(size_type __s) _NOEXCEPT {
21702208 _LIBCPP_ASSERT_INTERNAL(__s < __min_cap, "__s should never be greater than or equal to the short string capacity");
......@@ -2194,21 +2232,11 @@ private:
21942232 __set_short_size(__s);
21952233 }
21962234
2197 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_long_cap(size_type __s) _NOEXCEPT {
2198 _LIBCPP_ASSERT_INTERNAL(!__fits_in_sso(__s), "Long capacity should always be larger than the SSO");
2199 __rep_.__l.__cap_ = __s / __endian_factor;
2200 __rep_.__l.__is_long_ = true;
2201 }
2202
22032235 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __get_long_cap() const _NOEXCEPT {
22042236 _LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long capacity");
22052237 return __rep_.__l.__cap_ * __endian_factor;
22062238 }
22072239
2208 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_long_pointer(pointer __p) _NOEXCEPT {
2209 __rep_.__l.__data_ = __p;
2210 }
2211
22122240 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __get_long_pointer() _NOEXCEPT {
22132241 _LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long pointer");
22142242 return _LIBCPP_ASAN_VOLATILE_WRAPPER(__rep_.__l.__data_);
......@@ -2236,6 +2264,58 @@ private:
22362264 return __is_long() ? __get_long_pointer() : __get_short_pointer();
22372265 }
22382266
2267 // Internal buffer management
2268 // --------------------------
2269 //
2270 // These functions are only responsible for managing the buffer itself, not the value inside the buffer. As such,
2271 // none of these facilities ensure that there is a null terminator at `data()[size()]`.
2272
2273 // Allocate a buffer of __capacity size with __alloc and return it
2274 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 __long
2275 __allocate_long_buffer(_Allocator& __alloc, size_type __capacity) {
2276 _LIBCPP_ASSERT_INTERNAL(!__fits_in_sso(__capacity),
2277 "Trying to allocate long buffer for a capacity what would fit into the small buffer");
2278 auto __buffer = std::__allocate_at_least(__alloc, __align_allocation_size(__capacity));
2279
2280 if (__libcpp_is_constant_evaluated()) {
2281 for (size_type __i = 0; __i != __buffer.count; ++__i)
2282 std::__construct_at(std::addressof(__buffer.ptr[__i]));
2283 }
2284
2285 return __long(__buffer, __capacity);
2286 }
2287
2288 // Replace the current buffer with __new_rep. Deallocate the old long buffer if it exists.
2289 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __reset_internal_buffer(__rep __new_rep = __short()) {
2290 __annotate_delete();
2291 if (__is_long())
2292 __alloc_traits::deallocate(__alloc_, __get_long_pointer(), __get_long_cap());
2293 __rep_ = __new_rep;
2294 }
2295
2296 // Initialize the internal buffer to hold __size elements
2297 // The elements and null terminator have to be set by the caller
2298 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __init_internal_buffer(size_type __size) {
2299 if (__libcpp_is_constant_evaluated())
2300 __rep_ = __rep();
2301
2302 if (__size > max_size())
2303 __throw_length_error();
2304
2305 if (__fits_in_sso(__size)) {
2306 __set_short_size(__size);
2307 __annotate_new(__size);
2308 return __get_short_pointer();
2309 } else {
2310 __rep_.__l = __allocate_long_buffer(__alloc_, __size);
2311 __annotate_new(__size);
2312 return __get_long_pointer();
2313 }
2314 }
2315
2316 // ASan annotation helpers
2317 // -----------------------
2318
22392319 // The following functions are no-ops outside of AddressSanitizer mode.
22402320 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
22412321 __annotate_contiguous_container(const void* __old_mid, const void* __new_mid) const {
......@@ -2243,7 +2323,7 @@ private:
22432323 (void)__new_mid;
22442324# if _LIBCPP_INSTRUMENTED_WITH_ASAN
22452325# if defined(__APPLE__)
2246 // TODO: remove after addressing issue #96099 (https://github.com/llvm/llvm-project/issues/96099)
2326 // TODO: remove after addressing issue #96099 (https://llvm.org/PR96099)
22472327 if (!__is_long())
22482328 return;
22492329# endif
......@@ -2287,19 +2367,36 @@ private:
22872367 return (__s + (__a - 1)) & ~(__a - 1);
22882368 }
22892369 enum { __alignment = 8 };
2290 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __s) _NOEXCEPT {
2291 if (__s < __min_cap) {
2292 return static_cast<size_type>(__min_cap) - 1;
2293 }
2370
2371 // This makes sure that we're using a capacity with some extra alignment, since allocators almost always over-align
2372 // the allocations anyways, improving memory usage. More importantly, this ensures that the lowest bit is never set
2373 // if __endian_factor == 2, allowing us to store whether we're in the long string inside the lowest bit.
2374 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
2375 __align_allocation_size(size_type __size) _NOEXCEPT {
2376 _LIBCPP_ASSERT_INTERNAL(
2377 !__fits_in_sso(__size), "Trying to align allocation of a size which would fit into the SSO");
22942378 const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor;
2295 size_type __guess = __align_it<__boundary>(__s + 1) - 1;
2296 if (__guess == __min_cap)
2379 size_type __guess = __align_it<__boundary>(__size + 1);
2380 if (__guess == __min_cap + 1)
22972381 __guess += __endian_factor;
22982382
2299 _LIBCPP_ASSERT_INTERNAL(__guess >= __s, "recommendation is below the requested size");
2383 _LIBCPP_ASSERT_INTERNAL(__guess >= __size, "aligned allocation size is below the requested size");
23002384 return __guess;
23012385 }
23022386
2387 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
2388 __get_amortized_growth_capacity(size_type __required_capacity) {
2389 size_type __max_size = max_size();
2390 if (__required_capacity > __max_size)
2391 __throw_length_error();
2392 size_type __current_cap = capacity();
2393 _LIBCPP_ASSERT_INTERNAL(
2394 __current_cap < __required_capacity, "Trying to grow string even though there is enough capacity already?");
2395 if (__current_cap > __max_size / 2 - __alignment)
2396 return __max_size;
2397 return std::max(__required_capacity, 2 * __current_cap);
2398 }
2399
23032400 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(const value_type* __s, size_type __sz);
23042401 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(size_type __n, value_type __c);
23052402
......@@ -2366,7 +2463,8 @@ private:
23662463
23672464 // __erase_external_with_move is invoked for erase() invocations where
23682465 // `n ~= npos`, likely requiring memory moves on the string data.
2369 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void __erase_external_with_move(size_type __pos, size_type __n);
2466 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void
2467 __erase_external_with_move(size_type __pos, size_type __n) _NOEXCEPT;
23702468
23712469 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __copy_assign_alloc(const basic_string& __str) {
23722470 __copy_assign_alloc(
......@@ -2378,24 +2476,14 @@ private:
23782476 __alloc_ = __str.__alloc_;
23792477 else {
23802478 if (!__str.__is_long()) {
2381 if (__is_long()) {
2382 __annotate_delete();
2383 __alloc_traits::deallocate(__alloc_, __get_long_pointer(), __get_long_cap());
2384 __rep_ = __rep();
2385 }
2479 __reset_internal_buffer();
23862480 __alloc_ = __str.__alloc_;
23872481 } else {
23882482 __annotate_delete();
2389 auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
2390 allocator_type __a = __str.__alloc_;
2391 auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap());
2392 __begin_lifetime(__allocation.ptr, __allocation.count);
2393 if (__is_long())
2394 __alloc_traits::deallocate(__alloc_, __get_long_pointer(), __get_long_cap());
2395 __alloc_ = std::move(__a);
2396 __set_long_pointer(__allocation.ptr);
2397 __set_long_cap(__allocation.count);
2398 __set_long_size(__str.__get_long_size());
2483 auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
2484 auto __alloc = __str.__alloc_;
2485 __reset_internal_buffer(__allocate_long_buffer(__alloc, __str.size()));
2486 __alloc_ = std::move(__alloc);
23992487 }
24002488 }
24012489 }
......@@ -2507,26 +2595,55 @@ _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
25072595# endif
25082596# undef _LIBCPP_DECLARE
25092597
2598# if _LIBCPP_STD_VER <= 17 || !__has_builtin(__builtin_lt_synthesizes_from_spaceship)
2599template <class _CharT, class _Traits, class _Alloc>
2600struct __default_three_way_comparator<basic_string<_CharT, _Traits, _Alloc>, basic_string<_CharT, _Traits, _Alloc> > {
2601 using __string_t _LIBCPP_NODEBUG = basic_string<_CharT, _Traits, _Alloc>;
2602
2603 _LIBCPP_HIDE_FROM_ABI static int operator()(const __string_t& __lhs, const __string_t& __rhs) {
2604 auto __min_len = std::min(__lhs.size(), __rhs.size());
2605 auto __ret = _Traits::compare(__lhs.data(), __rhs.data(), __min_len);
2606 if (__ret == 0)
2607 return __lhs.size() == __rhs.size() ? 0 : __lhs.size() < __rhs.size() ? -1 : 1;
2608 return __ret;
2609 }
2610};
2611# endif
2612
2613template <class _Comparator, class _CharT, class _Traits, class _Alloc>
2614inline const bool __is_transparently_comparable_v<_Comparator,
2615 basic_string<_CharT, _Traits, _Alloc>,
2616 const _CharT*,
2617 __enable_if_t<__is_generic_transparent_comparator_v<_Comparator> > > =
2618 true;
2619
2620template <class _Comparator, class _CharT, class _Traits, class _Alloc, size_t _Np>
2621inline const bool __is_transparently_comparable_v<_Comparator,
2622 basic_string<_CharT, _Traits, _Alloc>,
2623 _CharT[_Np],
2624 __enable_if_t<__is_generic_transparent_comparator_v<_Comparator> > > =
2625 true;
2626
25102627# if _LIBCPP_STD_VER >= 17
25112628template <class _InputIterator,
2512 class _CharT = __iter_value_type<_InputIterator>,
2629 class _CharT = __iterator_value_type<_InputIterator>,
25132630 class _Allocator = allocator<_CharT>,
25142631 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
2515 class = enable_if_t<__is_allocator<_Allocator>::value> >
2632 class = enable_if_t<__is_allocator_v<_Allocator>>>
25162633basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
25172634 -> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
25182635
25192636template <class _CharT,
25202637 class _Traits,
25212638 class _Allocator = allocator<_CharT>,
2522 class = enable_if_t<__is_allocator<_Allocator>::value> >
2639 class = enable_if_t<__is_allocator_v<_Allocator>>>
25232640explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())
25242641 -> basic_string<_CharT, _Traits, _Allocator>;
25252642
25262643template <class _CharT,
25272644 class _Traits,
25282645 class _Allocator = allocator<_CharT>,
2529 class = enable_if_t<__is_allocator<_Allocator>::value>,
2646 class = enable_if_t<__is_allocator_v<_Allocator>>,
25302647 class _Sz = typename allocator_traits<_Allocator>::size_type >
25312648basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator())
25322649 -> basic_string<_CharT, _Traits, _Allocator>;
......@@ -2535,7 +2652,7 @@ basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _
25352652# if _LIBCPP_STD_VER >= 23
25362653template <ranges::input_range _Range,
25372654 class _Allocator = allocator<ranges::range_value_t<_Range>>,
2538 class = enable_if_t<__is_allocator<_Allocator>::value> >
2655 class = enable_if_t<__is_allocator_v<_Allocator>>>
25392656basic_string(from_range_t, _Range&&, _Allocator = _Allocator())
25402657 -> basic_string<ranges::range_value_t<_Range>, char_traits<ranges::range_value_t<_Range>>, _Allocator>;
25412658# endif
......@@ -2543,73 +2660,23 @@ basic_string(from_range_t, _Range&&, _Allocator = _Allocator())
25432660template <class _CharT, class _Traits, class _Allocator>
25442661_LIBCPP_CONSTEXPR_SINCE_CXX20 void
25452662basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) {
2546 if (__libcpp_is_constant_evaluated())
2547 __rep_ = __rep();
2548 if (__sz > max_size())
2549 this->__throw_length_error();
2550 pointer __p;
2551 if (__fits_in_sso(__sz)) {
2552 __set_short_size(__sz);
2553 __p = __get_short_pointer();
2554 } else {
2555 auto __allocation = std::__allocate_at_least(__alloc_, __recommend(__sz) + 1);
2556 __p = __allocation.ptr;
2557 __begin_lifetime(__p, __allocation.count);
2558 __set_long_pointer(__p);
2559 __set_long_cap(__allocation.count);
2560 __set_long_size(__sz);
2561 }
2663 pointer __p = __init_internal_buffer(__sz);
25622664 traits_type::copy(std::__to_address(__p), __s, __sz);
25632665 traits_type::assign(__p[__sz], value_type());
2564 __annotate_new(__sz);
25652666}
25662667
25672668template <class _CharT, class _Traits, class _Allocator>
25682669_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void
25692670basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(const value_type* __s, size_type __sz) {
2570 if (__libcpp_is_constant_evaluated())
2571 __rep_ = __rep();
2572
2573 pointer __p;
2574 if (__fits_in_sso(__sz)) {
2575 __p = __get_short_pointer();
2576 __set_short_size(__sz);
2577 } else {
2578 if (__sz > max_size())
2579 this->__throw_length_error();
2580 auto __allocation = std::__allocate_at_least(__alloc_, __recommend(__sz) + 1);
2581 __p = __allocation.ptr;
2582 __begin_lifetime(__p, __allocation.count);
2583 __set_long_pointer(__p);
2584 __set_long_cap(__allocation.count);
2585 __set_long_size(__sz);
2586 }
2671 pointer __p = __init_internal_buffer(__sz);
25872672 traits_type::copy(std::__to_address(__p), __s, __sz + 1);
2588 __annotate_new(__sz);
25892673}
25902674
25912675template <class _CharT, class _Traits, class _Allocator>
25922676_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) {
2593 if (__libcpp_is_constant_evaluated())
2594 __rep_ = __rep();
2595
2596 if (__n > max_size())
2597 this->__throw_length_error();
2598 pointer __p;
2599 if (__fits_in_sso(__n)) {
2600 __set_short_size(__n);
2601 __p = __get_short_pointer();
2602 } else {
2603 auto __allocation = std::__allocate_at_least(__alloc_, __recommend(__n) + 1);
2604 __p = __allocation.ptr;
2605 __begin_lifetime(__p, __allocation.count);
2606 __set_long_pointer(__p);
2607 __set_long_cap(__allocation.count);
2608 __set_long_size(__n);
2609 }
2677 pointer __p = __init_internal_buffer(__n);
26102678 traits_type::assign(std::__to_address(__p), __n, __c);
26112679 traits_type::assign(__p[__n], value_type());
2612 __annotate_new(__n);
26132680}
26142681
26152682template <class _CharT, class _Traits, class _Allocator>
......@@ -2626,19 +2693,10 @@ basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator _
26262693 __rep_ = __rep();
26272694 __annotate_new(0);
26282695
2629# if _LIBCPP_HAS_EXCEPTIONS
2630 try {
2631# endif // _LIBCPP_HAS_EXCEPTIONS
2632 for (; __first != __last; ++__first)
2633 push_back(*__first);
2634# if _LIBCPP_HAS_EXCEPTIONS
2635 } catch (...) {
2636 __annotate_delete();
2637 if (__is_long())
2638 __alloc_traits::deallocate(__alloc_, __get_long_pointer(), __get_long_cap());
2639 throw;
2640 }
2641# endif // _LIBCPP_HAS_EXCEPTIONS
2696 auto __guard = std::__make_exception_guard([this] { __reset_internal_buffer(); });
2697 for (; __first != __last; ++__first)
2698 push_back(*__first);
2699 __guard.__complete();
26422700}
26432701
26442702template <class _CharT, class _Traits, class _Allocator>
......@@ -2653,39 +2711,12 @@ template <class _CharT, class _Traits, class _Allocator>
26532711template <class _InputIterator, class _Sentinel>
26542712_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
26552713basic_string<_CharT, _Traits, _Allocator>::__init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz) {
2656 if (__libcpp_is_constant_evaluated())
2657 __rep_ = __rep();
2714 pointer __p = __init_internal_buffer(__sz);
26582715
2659 if (__sz > max_size())
2660 this->__throw_length_error();
2661
2662 pointer __p;
2663 if (__fits_in_sso(__sz)) {
2664 __set_short_size(__sz);
2665 __p = __get_short_pointer();
2666
2667 } else {
2668 auto __allocation = std::__allocate_at_least(__alloc_, __recommend(__sz) + 1);
2669 __p = __allocation.ptr;
2670 __begin_lifetime(__p, __allocation.count);
2671 __set_long_pointer(__p);
2672 __set_long_cap(__allocation.count);
2673 __set_long_size(__sz);
2674 }
2675
2676# if _LIBCPP_HAS_EXCEPTIONS
2677 try {
2678# endif // _LIBCPP_HAS_EXCEPTIONS
2679 auto __end = __copy_non_overlapping_range(std::move(__first), std::move(__last), std::__to_address(__p));
2680 traits_type::assign(*__end, value_type());
2681# if _LIBCPP_HAS_EXCEPTIONS
2682 } catch (...) {
2683 if (__is_long())
2684 __alloc_traits::deallocate(__alloc_, __get_long_pointer(), __get_long_cap());
2685 throw;
2686 }
2687# endif // _LIBCPP_HAS_EXCEPTIONS
2688 __annotate_new(__sz);
2716 auto __guard = std::__make_exception_guard([this] { __reset_internal_buffer(); });
2717 auto __end = __copy_non_overlapping_range(std::move(__first), std::move(__last), std::__to_address(__p));
2718 traits_type::assign(*__end, value_type());
2719 __guard.__complete();
26892720}
26902721
26912722template <class _CharT, class _Traits, class _Allocator>
......@@ -2697,32 +2728,22 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
26972728 size_type __n_del,
26982729 size_type __n_add,
26992730 const value_type* __p_new_stuff) {
2700 size_type __ms = max_size();
2701 if (__delta_cap > __ms - __old_cap)
2702 __throw_length_error();
2731 __long __buffer = __allocate_long_buffer(__alloc_, __get_amortized_growth_capacity(__old_cap + __delta_cap));
27032732 pointer __old_p = __get_pointer();
2704 size_type __cap =
2705 __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
27062733 __annotate_delete();
2707 auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
2708 auto __allocation = std::__allocate_at_least(__alloc_, __cap + 1);
2709 pointer __p = __allocation.ptr;
2710 __begin_lifetime(__p, __allocation.count);
2734 auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
27112735 if (__n_copy != 0)
2712 traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy);
2736 traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy);
27132737 if (__n_add != 0)
2714 traits_type::copy(std::__to_address(__p) + __n_copy, __p_new_stuff, __n_add);
2738 traits_type::copy(std::__to_address(__buffer.__data_) + __n_copy, __p_new_stuff, __n_add);
27152739 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
27162740 if (__sec_cp_sz != 0)
2717 traits_type::copy(
2718 std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz);
2719 if (__old_cap + 1 != __min_cap)
2720 __alloc_traits::deallocate(__alloc_, __old_p, __old_cap + 1);
2721 __set_long_pointer(__p);
2722 __set_long_cap(__allocation.count);
2723 __old_sz = __n_copy + __n_add + __sec_cp_sz;
2724 __set_long_size(__old_sz);
2725 traits_type::assign(__p[__old_sz], value_type());
2741 traits_type::copy(std::__to_address(__buffer.__data_) + __n_copy + __n_add,
2742 std::__to_address(__old_p) + __n_copy + __n_del,
2743 __sec_cp_sz);
2744 __buffer.__size_ = __n_copy + __n_add + __sec_cp_sz;
2745 traits_type::assign(__buffer.__data_[__buffer.__size_], value_type());
2746 __reset_internal_buffer(__buffer);
27262747}
27272748
27282749// __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it
......@@ -2740,25 +2761,20 @@ _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Trait
27402761 size_type __n_copy,
27412762 size_type __n_del,
27422763 size_type __n_add) {
2743 size_type __ms = max_size();
2744 if (__delta_cap > __ms - __old_cap)
2745 this->__throw_length_error();
2764 __long __buffer = __allocate_long_buffer(__alloc_, __get_amortized_growth_capacity(__old_cap + __delta_cap));
27462765 pointer __old_p = __get_pointer();
2747 size_type __cap =
2748 __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
2749 auto __allocation = std::__allocate_at_least(__alloc_, __cap + 1);
2750 pointer __p = __allocation.ptr;
2751 __begin_lifetime(__p, __allocation.count);
27522766 if (__n_copy != 0)
2753 traits_type::copy(std::__to_address(__p), std::__to_address(__old_p), __n_copy);
2767 traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy);
27542768 size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
27552769 if (__sec_cp_sz != 0)
2756 traits_type::copy(
2757 std::__to_address(__p) + __n_copy + __n_add, std::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz);
2758 if (__old_cap + 1 != __min_cap)
2759 __alloc_traits::deallocate(__alloc_, __old_p, __old_cap + 1);
2760 __set_long_pointer(__p);
2761 __set_long_cap(__allocation.count);
2770 traits_type::copy(std::__to_address(__buffer.__data_) + __n_copy + __n_add,
2771 std::__to_address(__old_p) + __n_copy + __n_del,
2772 __sec_cp_sz);
2773
2774 // This is -1 to make sure the caller sets the size properly, since old versions of this function didn't set the size
2775 // at all.
2776 __buffer.__size_ = -1;
2777 __reset_internal_buffer(__buffer);
27622778}
27632779
27642780template <class _CharT, class _Traits, class _Allocator>
......@@ -2775,6 +2791,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace(
27752791 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
27762792 __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add);
27772793 _LIBCPP_SUPPRESS_DEPRECATED_POP
2794 // Due to the ABI of __grow_by we have to set the size after calling it.
27782795 __set_long_size(__old_sz - __n_del + __n_add);
27792796}
27802797
......@@ -2786,24 +2803,23 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Al
27862803basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(const value_type* __s, size_type __n) {
27872804 const auto __cap = __is_short ? static_cast<size_type>(__min_cap) : __get_long_cap();
27882805 const auto __size = __is_short ? __get_short_size() : __get_long_size();
2789 if (__n < __cap) {
2790 if (__n > __size)
2791 __annotate_increase(__n - __size);
2792 pointer __p;
2793 if (__is_short) {
2794 __p = __get_short_pointer();
2795 __set_short_size(__n);
2796 } else {
2797 __p = __get_long_pointer();
2798 __set_long_size(__n);
2799 }
2800 traits_type::copy(std::__to_address(__p), __s, __n);
2801 traits_type::assign(__p[__n], value_type());
2802 if (__size > __n)
2803 __annotate_shrink(__size);
2804 } else {
2806 if (__n >= __cap) {
28052807 __grow_by_and_replace(__cap - 1, __n - __cap + 1, __size, 0, __size, __n, __s);
2808 return *this;
28062809 }
2810
2811 __annotate_delete();
2812 auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
2813 pointer __p;
2814 if (__is_short) {
2815 __p = __get_short_pointer();
2816 __set_short_size(__n);
2817 } else {
2818 __p = __get_long_pointer();
2819 __set_long_size(__n);
2820 }
2821 traits_type::copy(std::__to_address(__p), __s, __n);
2822 traits_type::assign(__p[__n], value_type());
28072823 return *this;
28082824}
28092825
......@@ -2910,7 +2926,7 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
29102926{
29112927 __annotate_delete();
29122928 if (__is_long()) {
2913 __alloc_traits::deallocate(__alloc_, __get_long_pointer(), __get_long_cap());
2929 __reset_internal_buffer();
29142930# if _LIBCPP_STD_VER <= 14
29152931 if (!is_nothrow_move_assignable<allocator_type>::value) {
29162932 __set_short_size(0);
......@@ -2961,7 +2977,7 @@ template <class _Iterator, class _Sentinel>
29612977_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
29622978basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n) {
29632979 _LIBCPP_ASSERT_INTERNAL(
2964 __string_is_trivial_iterator<_Iterator>::value, "The iterator type given to `__assign_trivial` must be trivial");
2980 __string_is_trivial_iterator_v<_Iterator>, "The iterator type given to `__assign_trivial` must be trivial");
29652981
29662982 size_type __old_size = size();
29672983 size_type __cap = capacity();
......@@ -3017,52 +3033,40 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty
30173033 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::append received nullptr");
30183034 size_type __cap = capacity();
30193035 size_type __sz = size();
3020 if (__cap - __sz >= __n) {
3021 if (__n) {
3022 __annotate_increase(__n);
3023 value_type* __p = std::__to_address(__get_pointer());
3024 traits_type::copy(__p + __sz, __s, __n);
3025 __sz += __n;
3026 __set_size(__sz);
3027 traits_type::assign(__p[__sz], value_type());
3028 }
3029 } else
3036 if (__cap - __sz < __n) {
30303037 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s);
3038 return *this;
3039 }
3040
3041 if (__n == 0)
3042 return *this;
3043
3044 __annotate_increase(__n);
3045 value_type* __p = std::__to_address(__get_pointer());
3046 traits_type::copy(__p + __sz, __s, __n);
3047 __sz += __n;
3048 __set_size(__sz);
3049 traits_type::assign(__p[__sz], value_type());
30313050 return *this;
30323051}
30333052
30343053template <class _CharT, class _Traits, class _Allocator>
30353054_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
30363055basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) {
3037 if (__n) {
3038 size_type __cap = capacity();
3039 size_type __sz = size();
3040 if (__cap - __sz < __n)
3041 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
3042 __annotate_increase(__n);
3043 pointer __p = __get_pointer();
3044 traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
3045 __sz += __n;
3046 __set_size(__sz);
3047 traits_type::assign(__p[__sz], value_type());
3048 }
3049 return *this;
3050}
3056 if (__n == 0)
3057 return *this;
30513058
3052template <class _CharT, class _Traits, class _Allocator>
3053_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
3054basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) {
3055 if (__n) {
3056 size_type __cap = capacity();
3057 size_type __sz = size();
3058 if (__cap - __sz < __n)
3059 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
3060 __annotate_increase(__n);
3061 pointer __p = __get_pointer();
3062 __sz += __n;
3063 __set_size(__sz);
3064 traits_type::assign(__p[__sz], value_type());
3065 }
3059 size_type __cap = capacity();
3060 size_type __sz = size();
3061 if (__cap - __sz < __n)
3062 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
3063 __annotate_increase(__n);
3064 pointer __p = __get_pointer();
3065 traits_type::assign(std::__to_address(__p) + __sz, __n, __c);
3066 __sz += __n;
3067 __set_size(__sz);
3068 traits_type::assign(__p[__sz], value_type());
3069 return *this;
30663070}
30673071
30683072template <class _CharT, class _Traits, class _Allocator>
......@@ -3120,23 +3124,27 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t
31203124 if (__pos > __sz)
31213125 this->__throw_out_of_range();
31223126 size_type __cap = capacity();
3123 if (__cap - __sz >= __n) {
3124 if (__n) {
3125 __annotate_increase(__n);
3126 value_type* __p = std::__to_address(__get_pointer());
3127 size_type __n_move = __sz - __pos;
3128 if (__n_move != 0) {
3129 if (std::__is_pointer_in_range(__p + __pos, __p + __sz, __s))
3130 __s += __n;
3131 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
3132 }
3133 traits_type::move(__p + __pos, __s, __n);
3134 __sz += __n;
3135 __set_size(__sz);
3136 traits_type::assign(__p[__sz], value_type());
3137 }
3138 } else
3127
3128 if (__cap - __sz < __n) {
31393129 __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
3130 return *this;
3131 }
3132
3133 if (__n == 0)
3134 return *this;
3135
3136 __annotate_increase(__n);
3137 value_type* __p = std::__to_address(__get_pointer());
3138 size_type __n_move = __sz - __pos;
3139 if (__n_move != 0) {
3140 if (std::__is_pointer_in_range(__p + __pos, __p + __sz, __s))
3141 __s += __n;
3142 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
3143 }
3144 traits_type::move(__p + __pos, __s, __n);
3145 __sz += __n;
3146 __set_size(__sz);
3147 traits_type::assign(__p[__sz], value_type());
31403148 return *this;
31413149}
31423150
......@@ -3146,24 +3154,26 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
31463154 size_type __sz = size();
31473155 if (__pos > __sz)
31483156 this->__throw_out_of_range();
3149 if (__n) {
3150 size_type __cap = capacity();
3151 value_type* __p;
3152 if (__cap - __sz >= __n) {
3153 __annotate_increase(__n);
3154 __p = std::__to_address(__get_pointer());
3155 size_type __n_move = __sz - __pos;
3156 if (__n_move != 0)
3157 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
3158 } else {
3159 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
3160 __p = std::__to_address(__get_long_pointer());
3161 }
3162 traits_type::assign(__p + __pos, __n, __c);
3163 __sz += __n;
3164 __set_size(__sz);
3165 traits_type::assign(__p[__sz], value_type());
3157
3158 if (__n == 0)
3159 return *this;
3160
3161 size_type __cap = capacity();
3162 value_type* __p;
3163 if (__cap - __sz >= __n) {
3164 __annotate_increase(__n);
3165 __p = std::__to_address(__get_pointer());
3166 size_type __n_move = __sz - __pos;
3167 if (__n_move != 0)
3168 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
3169 } else {
3170 __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
3171 __p = std::__to_address(__get_long_pointer());
31663172 }
3173 traits_type::assign(__p + __pos, __n, __c);
3174 __sz += __n;
3175 __set_size(__sz);
3176 traits_type::assign(__p[__sz], value_type());
31673177 return *this;
31683178}
31693179
......@@ -3176,7 +3186,7 @@ basic_string<_CharT, _Traits, _Allocator>::__insert_with_size(
31763186 if (__n == 0)
31773187 return begin() + __ip;
31783188
3179 if (__string_is_trivial_iterator<_Iterator>::value && !__addr_in_range(*__first)) {
3189 if (__string_is_trivial_iterator_v<_Iterator> && !__addr_in_range(*__first)) {
31803190 return __insert_from_safe_copy(__n, __ip, std::move(__first), std::move(__last));
31813191 } else {
31823192 const basic_string __temp(__init_with_sentinel_tag(), std::move(__first), std::move(__last), __alloc_);
......@@ -3237,38 +3247,38 @@ basic_string<_CharT, _Traits, _Allocator>::replace(
32373247 this->__throw_out_of_range();
32383248 __n1 = std::min(__n1, __sz - __pos);
32393249 size_type __cap = capacity();
3240 if (__cap - __sz + __n1 >= __n2) {
3241 value_type* __p = std::__to_address(__get_pointer());
3242 if (__n1 != __n2) {
3243 if (__n2 > __n1)
3244 __annotate_increase(__n2 - __n1);
3245 size_type __n_move = __sz - __pos - __n1;
3246 if (__n_move != 0) {
3247 if (__n1 > __n2) {
3248 traits_type::move(__p + __pos, __s, __n2);
3249 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
3250 return __null_terminate_at(__p, __sz + (__n2 - __n1));
3251 }
3252 if (std::__is_pointer_in_range(__p + __pos + 1, __p + __sz, __s)) {
3253 if (__p + __pos + __n1 <= __s)
3254 __s += __n2 - __n1;
3255 else // __p + __pos < __s < __p + __pos + __n1
3256 {
3257 traits_type::move(__p + __pos, __s, __n1);
3258 __pos += __n1;
3259 __s += __n2;
3260 __n2 -= __n1;
3261 __n1 = 0;
3262 }
3263 }
3250 if (__cap - __sz + __n1 < __n2) {
3251 __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
3252 return *this;
3253 }
3254
3255 value_type* __p = std::__to_address(__get_pointer());
3256 if (__n1 != __n2) {
3257 if (__n2 > __n1)
3258 __annotate_increase(__n2 - __n1);
3259 size_type __n_move = __sz - __pos - __n1;
3260 if (__n_move != 0) {
3261 if (__n1 > __n2) {
3262 traits_type::move(__p + __pos, __s, __n2);
32643263 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
3264 return __null_terminate_at(__p, __sz + (__n2 - __n1));
3265 }
3266 if (std::__is_pointer_in_range(__p + __pos + 1, __p + __sz, __s)) {
3267 if (__p + __pos + __n1 <= __s) {
3268 __s += __n2 - __n1;
3269 } else { // __p + __pos < __s < __p + __pos + __n1
3270 traits_type::move(__p + __pos, __s, __n1);
3271 __pos += __n1;
3272 __s += __n2;
3273 __n2 -= __n1;
3274 __n1 = 0;
3275 }
32653276 }
3277 traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
32663278 }
3267 traits_type::move(__p + __pos, __s, __n2);
3268 return __null_terminate_at(__p, __sz + (__n2 - __n1));
3269 } else
3270 __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
3271 return *this;
3279 }
3280 traits_type::move(__p + __pos, __s, __n2);
3281 return __null_terminate_at(__p, __sz + (__n2 - __n1));
32723282}
32733283
32743284template <class _CharT, class _Traits, class _Allocator>
......@@ -3320,16 +3330,17 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
33203330// Does not check __pos against size()
33213331template <class _CharT, class _Traits, class _Allocator>
33223332_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void
3323basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(size_type __pos, size_type __n) {
3324 if (__n) {
3325 size_type __sz = size();
3326 value_type* __p = std::__to_address(__get_pointer());
3327 __n = std::min(__n, __sz - __pos);
3328 size_type __n_move = __sz - __pos - __n;
3329 if (__n_move != 0)
3330 traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
3331 __null_terminate_at(__p, __sz - __n);
3332 }
3333basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(size_type __pos, size_type __n) _NOEXCEPT {
3334 if (__n == 0)
3335 return;
3336
3337 size_type __sz = size();
3338 value_type* __p = std::__to_address(__get_pointer());
3339 __n = std::min(__n, __sz - __pos);
3340 size_type __n_move = __sz - __pos - __n;
3341 if (__n_move != 0)
3342 traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
3343 __null_terminate_at(__p, __sz - __n);
33333344}
33343345
33353346template <class _CharT, class _Traits, class _Allocator>
......@@ -3396,16 +3407,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::re
33963407 __erase_to_end(__n);
33973408}
33983409
3399template <class _CharT, class _Traits, class _Allocator>
3400_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
3401basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) {
3402 size_type __sz = size();
3403 if (__n > __sz) {
3404 __append_default_init(__n - __sz);
3405 } else
3406 __erase_to_end(__n);
3407}
3408
34093410template <class _CharT, class _Traits, class _Allocator>
34103411_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) {
34113412 if (__requested_capacity > max_size())
......@@ -3418,31 +3419,23 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::re
34183419 return;
34193420
34203421 __annotation_guard __g(*this);
3421 auto __allocation = std::__allocate_at_least(__alloc_, __recommend(__requested_capacity) + 1);
3422 auto __size = size();
3423 __begin_lifetime(__allocation.ptr, __allocation.count);
3424 traits_type::copy(std::__to_address(__allocation.ptr), data(), __size + 1);
3425 if (__is_long())
3426 __alloc_traits::deallocate(__alloc_, __get_long_pointer(), __get_long_cap());
3427 __set_long_cap(__allocation.count);
3428 __set_long_size(__size);
3429 __set_long_pointer(__allocation.ptr);
3422 __long __buffer = __allocate_long_buffer(__alloc_, __requested_capacity);
3423 __buffer.__size_ = size();
3424 traits_type::copy(std::__to_address(__buffer.__data_), data(), __buffer.__size_ + 1);
3425 __reset_internal_buffer(__buffer);
34303426}
34313427
34323428template <class _CharT, class _Traits, class _Allocator>
34333429inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT {
3434 size_type __target_capacity = __recommend(size());
3435 if (__target_capacity == capacity())
3430 if (!__is_long())
34363431 return;
34373432
3438 _LIBCPP_ASSERT_INTERNAL(__is_long(), "Trying to shrink small string");
3439
3440 // We're a long string and we're shrinking into the small buffer.
34413433 const auto __ptr = __get_long_pointer();
34423434 const auto __size = __get_long_size();
34433435 const auto __cap = __get_long_cap();
34443436
3445 if (__fits_in_sso(__target_capacity)) {
3437 // We're a long string and we're shrinking into the small buffer.
3438 if (__fits_in_sso(__size)) {
34463439 __annotation_guard __g(*this);
34473440 __set_short_size(__size);
34483441 traits_type::copy(std::__to_address(__get_short_pointer()), std::__to_address(__ptr), __size + 1);
......@@ -3450,25 +3443,25 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
34503443 return;
34513444 }
34523445
3446 if (__align_allocation_size(__size) == __cap)
3447 return;
3448
34533449# if _LIBCPP_HAS_EXCEPTIONS
34543450 try {
34553451# endif // _LIBCPP_HAS_EXCEPTIONS
34563452 __annotation_guard __g(*this);
3457 auto __allocation = std::__allocate_at_least(__alloc_, __target_capacity + 1);
3453 __long __buffer = __allocate_long_buffer(__alloc_, __size);
34583454
34593455 // The Standard mandates shrink_to_fit() does not increase the capacity.
34603456 // With equal capacity keep the existing buffer. This avoids extra work
34613457 // due to swapping the elements.
3462 if (__allocation.count - 1 >= capacity()) {
3463 __alloc_traits::deallocate(__alloc_, __allocation.ptr, __allocation.count);
3458 if (__buffer.__cap_ * __endian_factor - 1 >= capacity()) {
3459 __alloc_traits::deallocate(__alloc_, __buffer.__data_, __buffer.__cap_ * __endian_factor);
34643460 return;
34653461 }
34663462
3467 __begin_lifetime(__allocation.ptr, __allocation.count);
3468 traits_type::copy(std::__to_address(__allocation.ptr), std::__to_address(__ptr), __size + 1);
3469 __alloc_traits::deallocate(__alloc_, __ptr, __cap);
3470 __set_long_cap(__allocation.count);
3471 __set_long_pointer(__allocation.ptr);
3463 traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__get_long_pointer()), __size + 1);
3464 __reset_internal_buffer(__buffer);
34723465# if _LIBCPP_HAS_EXCEPTIONS
34733466 } catch (...) {
34743467 return;
......@@ -3574,7 +3567,8 @@ operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
35743567
35753568template <class _CharT, class _Traits, class _Allocator>
35763569inline _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool
3577operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) _NOEXCEPT {
3570operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
3571 const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __rhs) _NOEXCEPT {
35783572 _LIBCPP_ASSERT_NON_NULL(__rhs != nullptr, "operator==(basic_string, char*): received nullptr");
35793573
35803574 using _String = basic_string<_CharT, _Traits, _Allocator>;
......@@ -3858,46 +3852,52 @@ swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Tra
38583852 __lhs.swap(__rhs);
38593853}
38603854
3861_LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10);
3862_LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10);
3863_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const string& __str, size_t* __idx = nullptr, int __base = 10);
3864_LIBCPP_EXPORTED_FROM_ABI long long stoll(const string& __str, size_t* __idx = nullptr, int __base = 10);
3865_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
3866
3867_LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr);
3868_LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr);
3869_LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr);
3870
3871_LIBCPP_EXPORTED_FROM_ABI string to_string(int __val);
3872_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val);
3873_LIBCPP_EXPORTED_FROM_ABI string to_string(long __val);
3874_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val);
3875_LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val);
3876_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val);
3877_LIBCPP_EXPORTED_FROM_ABI string to_string(float __val);
3878_LIBCPP_EXPORTED_FROM_ABI string to_string(double __val);
3879_LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val);
3855[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10);
3856[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long
3857stoul(const string& __str, size_t* __idx = nullptr, int __base = 10);
3858[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10);
3859[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long long
3860stoll(const string& __str, size_t* __idx = nullptr, int __base = 10);
3861[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long long
3862stoull(const string& __str, size_t* __idx = nullptr, int __base = 10);
3863
3864[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr);
3865[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr);
3866[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr);
3867
3868[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(int __val);
3869[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val);
3870[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long __val);
3871[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val);
3872[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val);
3873[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val);
3874[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(float __val);
3875[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(double __val);
3876[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val);
38803877
38813878# if _LIBCPP_HAS_WIDE_CHARACTERS
3882_LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3883_LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3884_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3885_LIBCPP_EXPORTED_FROM_ABI long long stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3886_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3887
3888_LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr);
3889_LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr);
3890_LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
3891
3892_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
3893_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
3894_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
3895_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
3896_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
3897_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
3898_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
3899_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
3900_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
3879[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3880[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3881[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long
3882stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3883[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long long
3884stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3885[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long long
3886stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
3887
3888[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr);
3889[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr);
3890[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
3891
3892[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
3893[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
3894[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
3895[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
3896[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
3897[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
3898[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
3899[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
3900[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
39013901# endif // _LIBCPP_HAS_WIDE_CHARACTERS
39023902
39033903template <class _CharT, class _Traits, class _Allocator>
......@@ -3906,7 +3906,7 @@ _LIBCPP_TEMPLATE_DATA_VIS const typename basic_string<_CharT, _Traits, _Allocato
39063906
39073907template <class _CharT, class _Allocator>
39083908struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> {
3909 _LIBCPP_HIDE_FROM_ABI size_t
3909 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t
39103910 operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT {
39113911 return std::__do_string_hash(__val.data(), __val.data() + __val.size());
39123912 }
......@@ -3977,30 +3977,31 @@ erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred) {
39773977// Literal suffixes for basic_string [basic.string.literals]
39783978inline namespace literals {
39793979inline namespace string_literals {
3980inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char>
3980[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char>
39813981operator""s(const char* __str, size_t __len) {
39823982 return basic_string<char>(__str, __len);
39833983}
39843984
39853985# if _LIBCPP_HAS_WIDE_CHARACTERS
3986inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<wchar_t>
3987operator""s(const wchar_t* __str, size_t __len) {
3986[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
3987_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<wchar_t> operator""s(const wchar_t* __str, size_t __len) {
39883988 return basic_string<wchar_t>(__str, __len);
39893989}
39903990# endif
39913991
39923992# if _LIBCPP_HAS_CHAR8_T
3993inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string<char8_t> operator""s(const char8_t* __str, size_t __len) {
3993[[__nodiscard__]] inline
3994 _LIBCPP_HIDE_FROM_ABI constexpr basic_string<char8_t> operator""s(const char8_t* __str, size_t __len) {
39943995 return basic_string<char8_t>(__str, __len);
39953996}
39963997# endif
39973998
3998inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char16_t>
3999operator""s(const char16_t* __str, size_t __len) {
3999[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
4000_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char16_t> operator""s(const char16_t* __str, size_t __len) {
40004001 return basic_string<char16_t>(__str, __len);
40014002}
40024003
4003inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char32_t>
4004[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char32_t>
40044005operator""s(const char32_t* __str, size_t __len) {
40054006 return basic_string<char32_t>(__str, __len);
40064007}
lib/libcxx/include/string_view+113-89
......@@ -130,6 +130,8 @@ namespace std {
130130 size_type copy(charT* s, size_type n, size_type pos = 0) const; // constexpr in C++20
131131
132132 constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
133 constexpr basic_string_view subview(size_type pos = 0,
134 size_type n = npos) const; // freestanding-deleted, since C++26
133135 constexpr int compare(basic_string_view s) const noexcept;
134136 constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;
135137 constexpr int compare(size_type pos1, size_type n1,
......@@ -318,9 +320,9 @@ public:
318320 _LIBCPP_HIDE_FROM_ABI basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
319321
320322 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
321 : __data_(__s),
322 __size_(__len) {
323# if _LIBCPP_STD_VER >= 14
323 _LIBCPP_DIAGNOSE_NULLPTR_IF(__len != 0 && __s == nullptr, " if len is not zero")
324 : __data_(__s), __size_(__len) {
325# if !defined(_LIBCPP_CXX03_LANG) && (!defined(_LIBCPP_COMPILER_GCC) || _LIBCPP_STD_VER >= 14)
324326 // Allocations must fit in `ptrdiff_t` for pointer arithmetic to work. If `__len` exceeds it, the input
325327 // range could not have been valid. Most likely the caller underflowed some arithmetic and inadvertently
326328 // passed in a negative length.
......@@ -352,7 +354,7 @@ public:
352354 : __data_(ranges::data(__r)), __size_(ranges::size(__r)) {}
353355# endif // _LIBCPP_STD_VER >= 23
354356
355 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s)
357 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s)
356358 : __data_(__s), __size_(std::__char_traits_length_checked<_Traits>(__s)) {}
357359
358360# if _LIBCPP_STD_VER >= 23
......@@ -360,11 +362,11 @@ public:
360362# endif
361363
362364 // [string.view.iterators], iterators
363 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return cbegin(); }
365 [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return cbegin(); }
364366
365 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return cend(); }
367 [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return cend(); }
366368
367 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
369 [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
368370# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
369371 return std::__make_bounded_iter(data(), data(), data() + size());
370372# else
......@@ -372,7 +374,7 @@ public:
372374# endif
373375 }
374376
375 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
377 [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
376378# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
377379 return std::__make_bounded_iter(data() + size(), data(), data() + size());
378380# else
......@@ -380,51 +382,54 @@ public:
380382# endif
381383 }
382384
383 _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
385 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator
386 rbegin() const _NOEXCEPT {
384387 return const_reverse_iterator(cend());
385388 }
386389
387 _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
390 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
388391 return const_reverse_iterator(cbegin());
389392 }
390393
391 _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT {
394 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator
395 crbegin() const _NOEXCEPT {
392396 return const_reverse_iterator(cend());
393397 }
394398
395 _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {
399 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {
396400 return const_reverse_iterator(cbegin());
397401 }
398402
399403 // [string.view.capacity], capacity
400 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }
404 [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }
401405
402 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return __size_; }
406 [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return __size_; }
403407
404 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
408 [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
405409 return numeric_limits<size_type>::max() / sizeof(value_type);
406410 }
407411
408412 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return __size_ == 0; }
409413
410414 // [string.view.access], element access
411 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __pos) const _NOEXCEPT {
415 [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference
416 operator[](size_type __pos) const _NOEXCEPT {
412417 return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos < size(), "string_view[] index out of bounds"), __data_[__pos];
413418 }
414419
415 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __pos) const {
420 [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __pos) const {
416421 return __pos >= size() ? (__throw_out_of_range("string_view::at"), __data_[0]) : __data_[__pos];
417422 }
418423
419 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {
424 [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {
420425 return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::front(): string is empty"), __data_[0];
421426 }
422427
423 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
428 [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
424429 return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::back(): string is empty"), __data_[__size_ - 1];
425430 }
426431
427 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_pointer data() const _NOEXCEPT { return __data_; }
432 [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_pointer data() const _NOEXCEPT { return __data_; }
428433
429434 // [string.view.modifiers], modifiers:
430435 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void remove_prefix(size_type __n) _NOEXCEPT {
......@@ -457,15 +462,23 @@ public:
457462 return __rlen;
458463 }
459464
460 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view substr(size_type __pos = 0, size_type __n = npos) const {
465 [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view
466 substr(size_type __pos = 0, size_type __n = npos) const {
461467 // Use the `__assume_valid` form of the constructor to avoid an unnecessary check. Any substring of a view is a
462468 // valid view. In particular, `size()` is known to be smaller than `numeric_limits<difference_type>::max()`, so the
463 // new size is also smaller. See also https://github.com/llvm/llvm-project/issues/91634.
469 // new size is also smaller. See also https://llvm.org/PR91634.
464470 return __pos > size() ? (__throw_out_of_range("string_view::substr"), basic_string_view())
465471 : basic_string_view(__assume_valid(), data() + __pos, std::min(__n, size() - __pos));
466472 }
467473
468 _LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT {
474# if _LIBCPP_STD_VER >= 26
475 [[nodiscard]]
476 _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view subview(size_type __pos = 0, size_type __n = npos) const {
477 return substr(__pos, __n);
478 }
479# endif
480
481 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT {
469482 size_type __rlen = std::min(size(), __sv.size());
470483 int __retval = _Traits::compare(data(), __sv.data(), __rlen);
471484 if (__retval == 0) // first __rlen chars matched
......@@ -473,217 +486,226 @@ public:
473486 return __retval;
474487 }
475488
476 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
489 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
477490 compare(size_type __pos1, size_type __n1, basic_string_view __sv) const {
478491 return substr(__pos1, __n1).compare(__sv);
479492 }
480493
481 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
494 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
482495 compare(size_type __pos1, size_type __n1, basic_string_view __sv, size_type __pos2, size_type __n2) const {
483496 return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
484497 }
485498
486 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int compare(const _CharT* __s) const _NOEXCEPT {
499 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
500 compare(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const _NOEXCEPT {
487501 return compare(basic_string_view(__s));
488502 }
489503
490 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
491 compare(size_type __pos1, size_type __n1, const _CharT* __s) const {
504 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
505 compare(size_type __pos1, size_type __n1, const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
492506 return substr(__pos1, __n1).compare(basic_string_view(__s));
493507 }
494508
495 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
496 compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const {
509 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
510 compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
511 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero") {
497512 return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
498513 }
499514
500515 // find
501 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
516 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
502517 find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
503 _LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
504518 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size());
505519 }
506520
507 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
521 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
522 find(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
508523 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
509524 }
510525
511 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
512 find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
526 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
527 find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
528 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
513529 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
514530 return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
515531 }
516532
517 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
518 find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
533 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
534 find(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
519535 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find(): received nullptr");
520536 return std::__str_find<value_type, size_type, traits_type, npos>(
521537 data(), size(), __s, __pos, traits_type::length(__s));
522538 }
523539
524540 // rfind
525 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
541 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
526542 rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
527 _LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
528543 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size());
529544 }
530545
531 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
546 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
532547 rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT {
533548 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
534549 }
535550
536 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
537 rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
551 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
552 rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
553 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
538554 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
539555 return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
540556 }
541557
542 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
543 rfind(const _CharT* __s, size_type __pos = npos) const _NOEXCEPT {
558 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
559 rfind(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
544560 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::rfind(): received nullptr");
545561 return std::__str_rfind<value_type, size_type, traits_type, npos>(
546562 data(), size(), __s, __pos, traits_type::length(__s));
547563 }
548564
549565 // find_first_of
550 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
566 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
551567 find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
552 _LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
553568 return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
554569 data(), size(), __s.data(), __pos, __s.size());
555570 }
556571
557 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
572 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
558573 find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
559574 return find(__c, __pos);
560575 }
561576
562 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
563 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
577 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
578 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
579 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
564580 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
565581 return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
566582 }
567583
568 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
569 find_first_of(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
584 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
585 find_first_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
570586 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_of(): received nullptr");
571587 return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
572588 data(), size(), __s, __pos, traits_type::length(__s));
573589 }
574590
575591 // find_last_of
576 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
592 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
577593 find_last_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
578 _LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
579594 return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
580595 data(), size(), __s.data(), __pos, __s.size());
581596 }
582597
583 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
598 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
584599 find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT {
585600 return rfind(__c, __pos);
586601 }
587602
588 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
589 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
603 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
604 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
605 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
590606 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
591607 return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
592608 }
593609
594 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
595 find_last_of(const _CharT* __s, size_type __pos = npos) const _NOEXCEPT {
610 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
611 find_last_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
596612 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_of(): received nullptr");
597613 return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
598614 data(), size(), __s, __pos, traits_type::length(__s));
599615 }
600616
601617 // find_first_not_of
602 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
618 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
603619 find_first_not_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
604 _LIBCPP_ASSERT_NON_NULL(
605 __s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
606620 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
607621 data(), size(), __s.data(), __pos, __s.size());
608622 }
609623
610 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
624 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
611625 find_first_not_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
612626 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
613627 }
614628
615 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
616 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
629 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
630 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
631 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
617632 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
618633 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
619634 }
620635
621 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
622 find_first_not_of(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
636 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
637 find_first_not_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {
623638 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
624639 return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
625640 data(), size(), __s, __pos, traits_type::length(__s));
626641 }
627642
628643 // find_last_not_of
629 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
644 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
630645 find_last_not_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
631 _LIBCPP_ASSERT_NON_NULL(
632 __s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
633646 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
634647 data(), size(), __s.data(), __pos, __s.size());
635648 }
636649
637 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
650 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
638651 find_last_not_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT {
639652 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
640653 }
641654
642 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
643 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
655 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
656 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
657 _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {
644658 _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
645659 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
646660 }
647661
648 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
649 find_last_not_of(const _CharT* __s, size_type __pos = npos) const _NOEXCEPT {
662 [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
663 find_last_not_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {
650664 _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
651665 return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
652666 data(), size(), __s, __pos, traits_type::length(__s));
653667 }
654668
655669# if _LIBCPP_STD_VER >= 20
656 constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(basic_string_view __s) const noexcept {
670 [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(basic_string_view __s) const noexcept {
657671 return size() >= __s.size() && compare(0, __s.size(), __s) == 0;
658672 }
659673
660 constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept {
674 [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept {
661675 return !empty() && _Traits::eq(front(), __c);
662676 }
663677
664 constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* __s) const noexcept {
678 [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool
679 starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
665680 return starts_with(basic_string_view(__s));
666681 }
667682
668 constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(basic_string_view __s) const noexcept {
683 [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(basic_string_view __s) const noexcept {
669684 return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0;
670685 }
671686
672 constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept {
687 [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept {
673688 return !empty() && _Traits::eq(back(), __c);
674689 }
675690
676 constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* __s) const noexcept {
691 [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool
692 ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {
677693 return ends_with(basic_string_view(__s));
678694 }
679695# endif
680696
681697# if _LIBCPP_STD_VER >= 23
682 constexpr _LIBCPP_HIDE_FROM_ABI bool contains(basic_string_view __sv) const noexcept { return find(__sv) != npos; }
698 [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(basic_string_view __sv) const noexcept {
699 return find(__sv) != npos;
700 }
683701
684 constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { return find(__c) != npos; }
702 [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept {
703 return find(__c) != npos;
704 }
685705
686 constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* __s) const { return find(__s) != npos; }
706 [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const {
707 return find(__s) != npos;
708 }
687709# endif
688710
689711private:
......@@ -886,7 +908,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Trai
886908// [string.view.hash]
887909template <class _CharT>
888910struct __string_view_hash : public __unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t> {
889 _LIBCPP_HIDE_FROM_ABI size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT {
911 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t
912 operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT {
890913 return std::__do_string_hash(__val.data(), __val.data() + __val.size());
891914 }
892915};
......@@ -913,30 +936,31 @@ struct hash<basic_string_view<wchar_t, char_traits<wchar_t> > > : __string_view_
913936# if _LIBCPP_STD_VER >= 14
914937inline namespace literals {
915938inline namespace string_view_literals {
916inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char> operator""sv(const char* __str, size_t __len) noexcept {
939[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char>
940operator""sv(const char* __str, size_t __len) noexcept {
917941 return basic_string_view<char>(__str, __len);
918942}
919943
920944# if _LIBCPP_HAS_WIDE_CHARACTERS
921inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<wchar_t>
945[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<wchar_t>
922946operator""sv(const wchar_t* __str, size_t __len) noexcept {
923947 return basic_string_view<wchar_t>(__str, __len);
924948}
925949# endif
926950
927951# if _LIBCPP_HAS_CHAR8_T
928inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char8_t>
952[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char8_t>
929953operator""sv(const char8_t* __str, size_t __len) noexcept {
930954 return basic_string_view<char8_t>(__str, __len);
931955}
932956# endif
933957
934inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char16_t>
958[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char16_t>
935959operator""sv(const char16_t* __str, size_t __len) noexcept {
936960 return basic_string_view<char16_t>(__str, __len);
937961}
938962
939inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char32_t>
963[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char32_t>
940964operator""sv(const char32_t* __str, size_t __len) noexcept {
941965 return basic_string_view<char32_t>(__str, __len);
942966}
lib/libcxx/include/strstream+10-10
......@@ -179,8 +179,8 @@ public:
179179 void swap(strstreambuf& __rhs);
180180
181181 void freeze(bool __freezefl = true);
182 char* str();
183 int pcount() const;
182 [[__nodiscard__]] char* str();
183 [[__nodiscard__]] int pcount() const;
184184
185185protected:
186186 int_type overflow(int_type __c = EOF) override;
......@@ -264,8 +264,8 @@ public:
264264 __sb_.swap(__rhs.__sb_);
265265 }
266266
267 _LIBCPP_HIDE_FROM_ABI strstreambuf* rdbuf() const { return const_cast<strstreambuf*>(&__sb_); }
268 _LIBCPP_HIDE_FROM_ABI char* str() { return __sb_.str(); }
267 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI strstreambuf* rdbuf() const { return const_cast<strstreambuf*>(&__sb_); }
268 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char* str() { return __sb_.str(); }
269269
270270private:
271271 strstreambuf __sb_;
......@@ -297,10 +297,10 @@ public:
297297 __sb_.swap(__rhs.__sb_);
298298 }
299299
300 _LIBCPP_HIDE_FROM_ABI strstreambuf* rdbuf() const { return const_cast<strstreambuf*>(&__sb_); }
300 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI strstreambuf* rdbuf() const { return const_cast<strstreambuf*>(&__sb_); }
301301 _LIBCPP_HIDE_FROM_ABI void freeze(bool __freezefl = true) { __sb_.freeze(__freezefl); }
302 _LIBCPP_HIDE_FROM_ABI char* str() { return __sb_.str(); }
303 _LIBCPP_HIDE_FROM_ABI int pcount() const { return __sb_.pcount(); }
302 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char* str() { return __sb_.str(); }
303 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int pcount() const { return __sb_.pcount(); }
304304
305305private:
306306 strstreambuf __sb_; // exposition only
......@@ -340,10 +340,10 @@ public:
340340 }
341341
342342 // Members:
343 _LIBCPP_HIDE_FROM_ABI strstreambuf* rdbuf() const { return const_cast<strstreambuf*>(&__sb_); }
343 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI strstreambuf* rdbuf() const { return const_cast<strstreambuf*>(&__sb_); }
344344 _LIBCPP_HIDE_FROM_ABI void freeze(bool __freezefl = true) { __sb_.freeze(__freezefl); }
345 _LIBCPP_HIDE_FROM_ABI int pcount() const { return __sb_.pcount(); }
346 _LIBCPP_HIDE_FROM_ABI char* str() { return __sb_.str(); }
345 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int pcount() const { return __sb_.pcount(); }
346 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char* str() { return __sb_.str(); }
347347
348348private:
349349 strstreambuf __sb_; // exposition only
lib/libcxx/include/syncstream+4-4
......@@ -317,9 +317,9 @@ public:
317317
318318 _LIBCPP_HIDE_FROM_ABI bool emit() { return emit(false); }
319319
320 _LIBCPP_HIDE_FROM_ABI streambuf_type* get_wrapped() const noexcept { return __wrapped_; }
320 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI streambuf_type* get_wrapped() const noexcept { return __wrapped_; }
321321
322 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
322 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
323323
324324 _LIBCPP_HIDE_FROM_ABI void set_emit_on_sync(bool __b) noexcept { __emit_on_sync_ = __b; }
325325
......@@ -496,9 +496,9 @@ public:
496496 }
497497 }
498498
499 _LIBCPP_HIDE_FROM_ABI streambuf_type* get_wrapped() const noexcept { return __sb_.get_wrapped(); }
499 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI streambuf_type* get_wrapped() const noexcept { return __sb_.get_wrapped(); }
500500
501 _LIBCPP_HIDE_FROM_ABI syncbuf_type* rdbuf() const noexcept {
501 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI syncbuf_type* rdbuf() const noexcept {
502502 return const_cast<syncbuf_type*>(std::addressof(__sb_));
503503 }
504504
lib/libcxx/include/tgmath.h+12-12
......@@ -18,22 +18,22 @@
1818*/
1919
2020#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
21# include <__cxx03/tgmath.h>
21# include <__cxx03/__config>
2222#else
2323# include <__config>
24#endif
2425
25# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26# pragma GCC system_header
27# endif
26#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27# pragma GCC system_header
28#endif
2829
29# ifdef __cplusplus
30# include <cmath>
31# include <complex>
32# else
33# if __has_include_next(<tgmath.h>)
34# include_next <tgmath.h>
35# endif
30#ifdef __cplusplus
31# include <cmath>
32# include <complex>
33#else
34# if __has_include_next(<tgmath.h>)
35# include_next <tgmath.h>
3636# endif
37#endif // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
37#endif
3838
3939#endif // _LIBCPP_TGMATH_H
lib/libcxx/include/tuple+242-212
......@@ -106,6 +106,11 @@ public:
106106
107107 void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); // constexpr in C++20
108108 constexpr void swap(const tuple&) const noexcept(see-below); // C++23
109
110 template<tuple-like UTuple>
111 friend constexpr bool operator==(const tuple& t, const UTuple& u); // C++23
112 template<tuple-like UTuple>
113 friend constexpr auto operator<=>(const tuple& t, const UTuple& u); // C++23
109114};
110115
111116
......@@ -220,19 +225,16 @@ template <class... Types>
220225# include <__config>
221226# include <__cstddef/size_t.h>
222227# include <__fwd/array.h>
228# include <__fwd/get.h>
223229# include <__fwd/pair.h>
224230# include <__fwd/tuple.h>
225231# include <__memory/allocator_arg_t.h>
226232# include <__memory/uses_allocator.h>
227233# include <__tuple/find_index.h>
228234# include <__tuple/ignore.h>
229# include <__tuple/make_tuple_types.h>
230# include <__tuple/sfinae_helpers.h>
231235# include <__tuple/tuple_element.h>
232# include <__tuple/tuple_indices.h>
233# include <__tuple/tuple_like_ext.h>
236# include <__tuple/tuple_like.h>
234237# include <__tuple/tuple_size.h>
235# include <__tuple/tuple_types.h>
236238# include <__type_traits/common_reference.h>
237239# include <__type_traits/common_type.h>
238240# include <__type_traits/conditional.h>
......@@ -241,7 +243,6 @@ template <class... Types>
241243# include <__type_traits/disjunction.h>
242244# include <__type_traits/enable_if.h>
243245# include <__type_traits/invoke.h>
244# include <__type_traits/is_arithmetic.h>
245246# include <__type_traits/is_assignable.h>
246247# include <__type_traits/is_constructible.h>
247248# include <__type_traits/is_convertible.h>
......@@ -251,7 +252,6 @@ template <class... Types>
251252# include <__type_traits/is_nothrow_assignable.h>
252253# include <__type_traits/is_nothrow_constructible.h>
253254# include <__type_traits/is_reference.h>
254# include <__type_traits/is_replaceable.h>
255255# include <__type_traits/is_same.h>
256256# include <__type_traits/is_swappable.h>
257257# include <__type_traits/is_trivially_relocatable.h>
......@@ -263,12 +263,12 @@ template <class... Types>
263263# include <__type_traits/remove_cv.h>
264264# include <__type_traits/remove_cvref.h>
265265# include <__type_traits/remove_reference.h>
266# include <__type_traits/type_list.h>
266267# include <__type_traits/unwrap_ref.h>
267268# include <__utility/declval.h>
268269# include <__utility/forward.h>
269270# include <__utility/integer_sequence.h>
270271# include <__utility/move.h>
271# include <__utility/piecewise_construct.h>
272272# include <__utility/swap.h>
273273# include <version>
274274
......@@ -288,9 +288,65 @@ _LIBCPP_BEGIN_NAMESPACE_STD
288288
289289# ifndef _LIBCPP_CXX03_LANG
290290
291template <size_t _Ip, class _Tp, class _Up>
292_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool __tuple_compare_equal(const _Tp& __x, const _Up& __y) {
293 if constexpr (_Ip == 0)
294 return true;
295 else
296 return std::__tuple_compare_equal<_Ip - 1>(__x, __y) && std::get<_Ip - 1>(__x) == std::get<_Ip - 1>(__y);
297}
298
299# if _LIBCPP_STD_VER >= 26
300template <class _Tp, class _Up, class _IndexSeq = make_index_sequence<tuple_size_v<_Tp>>>
301inline constexpr bool __can_tuple_compare_equal = false;
302
303// TODO(LLVM 23): Remove `tuple_size_v<_Tp> == tuple_size_v<_Up>` here once once LLVM-20 support ends
304// because the resolution of CWG2369 landed in LLVM-21.
305template <class _Tp, class _Up, size_t... _Is>
306 requires(tuple_size_v<_Tp> == tuple_size_v<_Up>)
307inline constexpr bool __can_tuple_compare_equal<_Tp, _Up, index_sequence<_Is...>> =
308 __all<requires(const tuple_element_t<_Is, _Tp>& __t, const tuple_element_t<_Is, _Up>& __u) {
309 { __t == __u } -> __boolean_testable;
310 }...>::value;
311# endif // _LIBCPP_STD_VER >= 26
312
313# if _LIBCPP_STD_VER >= 20
314template <class _Ret, class _Tp, class _Up, size_t... _Is>
315_LIBCPP_HIDE_FROM_ABI constexpr _Ret __tuple_compare_three_way(const _Tp& __x, const _Up& __y, index_sequence<_Is...>) {
316 _Ret __result = strong_ordering::equal;
317 static_cast<void>(
318 ((__result = std::__synth_three_way(std::get<_Is>(__x), std::get<_Is>(__y)), __result != 0) || ...));
319 return __result;
320}
321# endif // _LIBCPP_STD_VER >= 20
322
323# if _LIBCPP_STD_VER >= 23
324template <class _Tp>
325concept __tuple_like_no_tuple = __tuple_like<_Tp> && !__is_tuple_v<_Tp>;
326
327template <class _Tp, class _Up, class _IndexSeq>
328struct __tuple_common_comparison_category_impl {};
329
330// TODO(LLVM 23): Remove `tuple_size_v<_Tp> == tuple_size_v<_Up>` here once once LLVM-20 support ends
331// because the resolution of CWG2369 landed in LLVM-21.
332template <class _Tp, class _Up, size_t... _Is>
333 requires(tuple_size_v<_Tp> == tuple_size_v<_Up>) && requires {
334 typename common_comparison_category_t<
335 __synth_three_way_result<tuple_element_t<_Is, _Tp>, tuple_element_t<_Is, _Up>>...>;
336 }
337struct __tuple_common_comparison_category_impl<_Tp, _Up, index_sequence<_Is...>> {
338 using type _LIBCPP_NODEBUG =
339 common_comparison_category_t<__synth_three_way_result<tuple_element_t<_Is, _Tp>, tuple_element_t<_Is, _Up>>...>;
340};
341
342template <__tuple_like _Tp, __tuple_like _Up>
343using __tuple_common_comparison_category _LIBCPP_NODEBUG =
344 __tuple_common_comparison_category_impl<_Tp, _Up, make_index_sequence<tuple_size_v<_Tp>>>::type;
345# endif // _LIBCPP_STD_VER >= 23
346
291347// __tuple_leaf
292348
293template <size_t _Ip, class _Hp, bool = is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value >
349template <size_t _Ip, class _Hp, bool = is_empty<_Hp>::value && !__is_final_v<_Hp> >
294350class __tuple_leaf;
295351
296352template <size_t _Ip, class _Hp, bool _Ep>
......@@ -444,62 +500,52 @@ public:
444500template <class... _Tp>
445501_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __swallow(_Tp&&...) _NOEXCEPT {}
446502
447template <class _Tp>
448struct __all_default_constructible;
449
450template <class... _Tp>
451struct __all_default_constructible<__tuple_types<_Tp...>> : __all<is_default_constructible<_Tp>::value...> {};
452
453503// __tuple_impl
454504
455505template <class _Indx, class... _Tp>
456506struct __tuple_impl;
457507
508struct __forward_args {};
509struct __value_init {};
510struct __from_tuple {};
511
458512template <size_t... _Indx, class... _Tp>
459513struct _LIBCPP_DECLSPEC_EMPTY_BASES
460 __tuple_impl<__tuple_indices<_Indx...>, _Tp...> : public __tuple_leaf<_Indx, _Tp>... {
514 __tuple_impl<__index_sequence<_Indx...>, _Tp...> : public __tuple_leaf<_Indx, _Tp>... {
461515 _LIBCPP_HIDE_FROM_ABI constexpr __tuple_impl() noexcept(
462516 __all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
463517
464 template <size_t... _Uf, class... _Tf, size_t... _Ul, class... _Tl, class... _Up>
465 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_impl(
466 __tuple_indices<_Uf...>,
467 __tuple_types<_Tf...>,
468 __tuple_indices<_Ul...>,
469 __tuple_types<_Tl...>,
470 _Up&&... __u) noexcept(__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
471 __all<is_nothrow_default_constructible<_Tl>::value...>::value)
472 : __tuple_leaf<_Uf, _Tf>(std::forward<_Up>(__u))..., __tuple_leaf<_Ul, _Tl>()... {}
473
474 template <class _Alloc, size_t... _Uf, class... _Tf, size_t... _Ul, class... _Tl, class... _Up>
518 template <class... _Args>
519 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_impl(__forward_args, _Args&&... __args)
520 : __tuple_leaf<_Indx, _Tp>(std::forward<_Args>(__args))... {}
521
522 template <class _Alloc>
523 _LIBCPP_HIDE_FROM_ABI
524 _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_impl(allocator_arg_t, const _Alloc& __alloc, __value_init)
525 : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc>(), __alloc)... {}
526
527 template <class _Alloc, class... _Args>
475528 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __tuple_impl(
476 allocator_arg_t,
477 const _Alloc& __a,
478 __tuple_indices<_Uf...>,
479 __tuple_types<_Tf...>,
480 __tuple_indices<_Ul...>,
481 __tuple_types<_Tl...>,
482 _Up&&... __u)
483 : __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a, std::forward<_Up>(__u))...,
484 __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)... {}
485
486 template <class _Tuple, __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value, int> = 0>
487 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __tuple_impl(_Tuple&& __t) noexcept(
488 (__all<is_nothrow_constructible<
489 _Tp,
490 typename tuple_element<_Indx, typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
529 allocator_arg_t, const _Alloc& __alloc, __forward_args, _Args&&... __args)
530 : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, _Args>(), __alloc, std::forward<_Args>(__args))... {}
531
532 template <class _Tuple>
533 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __tuple_impl(__from_tuple, _Tuple&& __t) noexcept(
534 (__all<is_nothrow_constructible<_Tp, __copy_cvref_t<_Tuple, __tuple_element_t<_Indx, __remove_cvref_t<_Tuple>>>>::
535 value...>::value))
491536 : __tuple_leaf<_Indx, _Tp>(
492 std::forward<typename tuple_element<_Indx, typename __make_tuple_types<_Tuple>::type>::type>(
537 std::forward<__copy_cvref_t<_Tuple, __tuple_element_t<_Indx, __remove_cvref_t<_Tuple>>>>(
493538 std::get<_Indx>(__t)))... {}
494539
495 template <class _Alloc, class _Tuple, __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value, int> = 0>
496 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
540 template <class _Alloc, class _Tuple>
541 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
542 __tuple_impl(allocator_arg_t, const _Alloc& __a, __from_tuple, _Tuple&& __t)
497543 : __tuple_leaf<_Indx, _Tp>(
498544 __uses_alloc_ctor<_Tp,
499545 _Alloc,
500 typename tuple_element<_Indx, typename __make_tuple_types<_Tuple>::type>::type>(),
546 __copy_cvref_t<_Tuple, __tuple_element_t<_Indx, __remove_cvref_t<_Tuple>>>>(),
501547 __a,
502 std::forward<typename tuple_element<_Indx, typename __make_tuple_types<_Tuple>::type>::type>(
548 std::forward<__copy_cvref_t<_Tuple, __tuple_element_t<_Indx, __remove_cvref_t<_Tuple>>>>(
503549 std::get<_Indx>(__t)))... {}
504550
505551 __tuple_impl(const __tuple_impl&) = default;
......@@ -518,19 +564,19 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES
518564
519565template <class _Dest, class _Source, size_t... _Np>
520566_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
521__memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
567__memberwise_copy_assign(_Dest& __dest, _Source const& __source, __index_sequence<_Np...>) {
522568 std::__swallow(((std::get<_Np>(__dest) = std::get<_Np>(__source)), void(), 0)...);
523569}
524570
525571template <class _Dest, class _Source, class... _Up, size_t... _Np>
526572_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
527__memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
573__memberwise_forward_assign(_Dest& __dest, _Source&& __source, __type_list<_Up...>, __index_sequence<_Np...>) {
528574 std::__swallow(((std::get<_Np>(__dest) = std::forward<_Up>(std::get<_Np>(__source))), void(), 0)...);
529575}
530576
531577template <class... _Tp>
532578class _LIBCPP_NO_SPECIALIZATIONS tuple {
533 typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
579 typedef __tuple_impl<__index_sequence_for<_Tp...>, _Tp...> _BaseT;
534580
535581 _BaseT __base_;
536582
......@@ -549,7 +595,6 @@ class _LIBCPP_NO_SPECIALIZATIONS tuple {
549595public:
550596 using __trivially_relocatable _LIBCPP_NODEBUG =
551597 __conditional_t<_And<__libcpp_is_trivially_relocatable<_Tp>...>::value, tuple, void>;
552 using __replaceable _LIBCPP_NODEBUG = __conditional_t<_And<__is_replaceable<_Tp>...>::value, tuple, void>;
553598
554599 // [tuple.cnstr]
555600
......@@ -566,12 +611,7 @@ public:
566611 __enable_if_t< _And< _IsDefault<_Tp>... >::value, int> = 0>
567612 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, _IsImpDefault<_Tp>...> >::value)
568613 tuple(allocator_arg_t, _Alloc const& __a)
569 : __base_(allocator_arg_t(),
570 __a,
571 __tuple_indices<>(),
572 __tuple_types<>(),
573 typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
574 __tuple_types<_Tp...>()) {}
614 : __base_(allocator_arg_t(), __a, __value_init{}) {}
575615
576616 // tuple(const T&...) constructors (including allocator_arg_t variants)
577617 template <template <class...> class _And = _And,
......@@ -579,11 +619,7 @@ public:
579619 _LIBCPP_HIDE_FROM_ABI
580620 _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> >::value)
581621 tuple(const _Tp&... __t) noexcept(_And<is_nothrow_copy_constructible<_Tp>...>::value)
582 : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
583 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
584 typename __make_tuple_indices<0>::type(),
585 typename __make_tuple_types<tuple, 0>::type(),
586 __t...) {}
622 : __base_(__forward_args{}, __t...) {}
587623
588624 template <class _Alloc,
589625 template <class...> class _And = _And,
......@@ -591,13 +627,7 @@ public:
591627 _LIBCPP_HIDE_FROM_ABI
592628 _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> >::value)
593629 tuple(allocator_arg_t, const _Alloc& __a, const _Tp&... __t)
594 : __base_(allocator_arg_t(),
595 __a,
596 typename __make_tuple_indices<sizeof...(_Tp)>::type(),
597 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
598 typename __make_tuple_indices<0>::type(),
599 typename __make_tuple_types<tuple, 0>::type(),
600 __t...) {}
630 : __base_(allocator_arg_t(), __a, __forward_args{}, __t...) {}
601631
602632 // tuple(U&& ...) constructors (including allocator_arg_t variants)
603633 template <class... _Up>
......@@ -616,11 +646,7 @@ public:
616646 int> = 0>
617647 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value)
618648 tuple(_Up&&... __u) noexcept(_And<is_nothrow_constructible<_Tp, _Up>...>::value)
619 : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
620 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
621 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
622 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
623 std::forward<_Up>(__u)...) {}
649 : __base_(__forward_args{}, std::forward<_Up>(__u)...) {}
624650
625651 template <class _Alloc,
626652 class... _Up,
......@@ -628,13 +654,7 @@ public:
628654 int> = 0>
629655 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value)
630656 tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
631 : __base_(allocator_arg_t(),
632 __a,
633 typename __make_tuple_indices<sizeof...(_Up)>::type(),
634 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
635 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
636 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
637 std::forward<_Up>(__u)...) {}
657 : __base_(allocator_arg_t(), __a, __forward_args{}, std::forward<_Up>(__u)...) {}
638658
639659 // Copy and move constructors (including the allocator_arg_t variants)
640660 tuple(const tuple&) = default;
......@@ -644,13 +664,13 @@ public:
644664 template <class...> class _And = _And,
645665 __enable_if_t< _And<is_copy_constructible<_Tp>...>::value, int> = 0>
646666 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
647 : __base_(allocator_arg_t(), __alloc, __t) {}
667 : __base_(allocator_arg_t(), __alloc, __from_tuple(), __t) {}
648668
649669 template <class _Alloc,
650670 template <class...> class _And = _And,
651671 __enable_if_t< _And<is_move_constructible<_Tp>...>::value, int> = 0>
652672 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
653 : __base_(allocator_arg_t(), __alloc, std::move(__t)) {}
673 : __base_(allocator_arg_t(), __alloc, __from_tuple(), std::move(__t)) {}
654674
655675 // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
656676
......@@ -683,7 +703,7 @@ public:
683703 _LIBCPP_HIDE_FROM_ABI
684704 _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> >::value)
685705 tuple(const tuple<_Up...>& __t) noexcept(_And<is_nothrow_constructible<_Tp, const _Up&>...>::value)
686 : __base_(__t) {}
706 : __base_(__from_tuple(), __t) {}
687707
688708 template <class... _Up,
689709 class _Alloc,
......@@ -691,33 +711,33 @@ public:
691711 _LIBCPP_HIDE_FROM_ABI
692712 _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> >::value)
693713 tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
694 : __base_(allocator_arg_t(), __a, __t) {}
714 : __base_(allocator_arg_t(), __a, __from_tuple(), __t) {}
695715
696716# if _LIBCPP_STD_VER >= 23
697717 // tuple(tuple<U...>&) constructors (including allocator_arg_t variants)
698718
699719 template <class... _Up, enable_if_t< _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
700720 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_Lazy<_And, is_convertible<_Up&, _Tp>...>::value) tuple(tuple<_Up...>& __t)
701 : __base_(__t) {}
721 : __base_(__from_tuple(), __t) {}
702722
703723 template <class _Alloc, class... _Up, enable_if_t< _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
704724 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_Lazy<_And, is_convertible<_Up&, _Tp>...>::value)
705725 tuple(allocator_arg_t, const _Alloc& __alloc, tuple<_Up...>& __t)
706 : __base_(allocator_arg_t(), __alloc, __t) {}
726 : __base_(allocator_arg_t(), __alloc, __from_tuple(), __t) {}
707727# endif // _LIBCPP_STD_VER >= 23
708728
709729 // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
710730 template <class... _Up, __enable_if_t< _And< _EnableCtorFromUTypesTuple<tuple<_Up...>&&> >::value, int> = 0>
711731 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value)
712732 tuple(tuple<_Up...>&& __t) noexcept(_And<is_nothrow_constructible<_Tp, _Up>...>::value)
713 : __base_(std::move(__t)) {}
733 : __base_(__from_tuple(), std::move(__t)) {}
714734
715735 template <class _Alloc,
716736 class... _Up,
717737 __enable_if_t< _And< _EnableCtorFromUTypesTuple<tuple<_Up...>&&> >::value, int> = 0>
718738 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value)
719739 tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
720 : __base_(allocator_arg_t(), __a, std::move(__t)) {}
740 : __base_(allocator_arg_t(), __a, __from_tuple(), std::move(__t)) {}
721741
722742# if _LIBCPP_STD_VER >= 23
723743 // tuple(const tuple<U...>&&) constructors (including allocator_arg_t variants)
......@@ -725,14 +745,14 @@ public:
725745 template <class... _Up, enable_if_t< _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
726746 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_Lazy<_And, is_convertible<const _Up&&, _Tp>...>::value)
727747 tuple(const tuple<_Up...>&& __t)
728 : __base_(std::move(__t)) {}
748 : __base_(__from_tuple(), std::move(__t)) {}
729749
730750 template <class _Alloc,
731751 class... _Up,
732752 enable_if_t< _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
733753 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_Lazy<_And, is_convertible<const _Up&&, _Tp>...>::value)
734754 tuple(allocator_arg_t, const _Alloc& __alloc, const tuple<_Up...>&& __t)
735 : __base_(allocator_arg_t(), __alloc, std::move(__t)) {}
755 : __base_(allocator_arg_t(), __alloc, __from_tuple(), std::move(__t)) {}
736756# endif // _LIBCPP_STD_VER >= 23
737757
738758 // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
......@@ -767,7 +787,7 @@ public:
767787 _LIBCPP_HIDE_FROM_ABI
768788 _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> >::value)
769789 tuple(const pair<_Up1, _Up2>& __p) noexcept(_NothrowConstructibleFromPair<const pair<_Up1, _Up2>&>::value)
770 : __base_(__p) {}
790 : __base_(__from_tuple(), __p) {}
771791
772792 template <class _Alloc,
773793 class _Up1,
......@@ -777,7 +797,7 @@ public:
777797 _LIBCPP_HIDE_FROM_ABI
778798 _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> >::value)
779799 tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
780 : __base_(allocator_arg_t(), __a, __p) {}
800 : __base_(allocator_arg_t(), __a, __from_tuple(), __p) {}
781801
782802# if _LIBCPP_STD_VER >= 23
783803 // tuple(pair<U1, U2>&) constructors (including allocator_arg_t variants)
......@@ -785,7 +805,7 @@ public:
785805 template <class _U1, class _U2, enable_if_t< _EnableCtorFromPair<pair<_U1, _U2>&>::value>* = nullptr>
786806 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value)
787807 tuple(pair<_U1, _U2>& __p)
788 : __base_(__p) {}
808 : __base_(__from_tuple(), __p) {}
789809
790810 template <class _Alloc,
791811 class _U1,
......@@ -793,7 +813,7 @@ public:
793813 enable_if_t< _EnableCtorFromPair<std::pair<_U1, _U2>&>::value>* = nullptr>
794814 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value)
795815 tuple(allocator_arg_t, const _Alloc& __alloc, pair<_U1, _U2>& __p)
796 : __base_(allocator_arg_t(), __alloc, __p) {}
816 : __base_(allocator_arg_t(), __alloc, __from_tuple(), __p) {}
797817# endif
798818
799819 // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
......@@ -805,7 +825,7 @@ public:
805825 _LIBCPP_HIDE_FROM_ABI
806826 _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(_Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> >::value)
807827 tuple(pair<_Up1, _Up2>&& __p) noexcept(_NothrowConstructibleFromPair<pair<_Up1, _Up2>&&>::value)
808 : __base_(std::move(__p)) {}
828 : __base_(__from_tuple(), std::move(__p)) {}
809829
810830 template <class _Alloc,
811831 class _Up1,
......@@ -815,7 +835,7 @@ public:
815835 _LIBCPP_HIDE_FROM_ABI
816836 _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(_Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> >::value)
817837 tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
818 : __base_(allocator_arg_t(), __a, std::move(__p)) {}
838 : __base_(allocator_arg_t(), __a, __from_tuple(), std::move(__p)) {}
819839
820840# if _LIBCPP_STD_VER >= 23
821841 // tuple(const pair<U1, U2>&&) constructors (including allocator_arg_t variants)
......@@ -823,7 +843,7 @@ public:
823843 template <class _U1, class _U2, enable_if_t< _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr>
824844 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
825845 tuple(const pair<_U1, _U2>&& __p)
826 : __base_(std::move(__p)) {}
846 : __base_(__from_tuple(), std::move(__p)) {}
827847
828848 template <class _Alloc,
829849 class _U1,
......@@ -831,14 +851,14 @@ public:
831851 enable_if_t< _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr>
832852 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
833853 tuple(allocator_arg_t, const _Alloc& __alloc, const pair<_U1, _U2>&& __p)
834 : __base_(allocator_arg_t(), __alloc, std::move(__p)) {}
854 : __base_(allocator_arg_t(), __alloc, __from_tuple(), std::move(__p)) {}
835855# endif // _LIBCPP_STD_VER >= 23
836856
837857 // [tuple.assign]
838858 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
839859 operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple) noexcept(
840860 _And<is_nothrow_copy_assignable<_Tp>...>::value) {
841 std::__memberwise_copy_assign(*this, __tuple, typename __make_tuple_indices<sizeof...(_Tp)>::type());
861 std::__memberwise_copy_assign(*this, __tuple, __index_sequence_for<_Tp...>());
842862 return *this;
843863 }
844864
......@@ -846,15 +866,14 @@ public:
846866 _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(tuple const& __tuple) const
847867 requires(_And<is_copy_assignable<const _Tp>...>::value)
848868 {
849 std::__memberwise_copy_assign(*this, __tuple, typename __make_tuple_indices<sizeof...(_Tp)>::type());
869 std::__memberwise_copy_assign(*this, __tuple, __index_sequence_for<_Tp...>());
850870 return *this;
851871 }
852872
853873 _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(tuple&& __tuple) const
854874 requires(_And<is_assignable<const _Tp&, _Tp>...>::value)
855875 {
856 std::__memberwise_forward_assign(
857 *this, std::move(__tuple), __tuple_types<_Tp...>(), typename __make_tuple_indices<sizeof...(_Tp)>::type());
876 std::__memberwise_forward_assign(*this, std::move(__tuple), __type_list<_Tp...>(), __index_sequence_for<_Tp...>());
858877 return *this;
859878 }
860879# endif // _LIBCPP_STD_VER >= 23
......@@ -862,8 +881,7 @@ public:
862881 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
863882 operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple) noexcept(
864883 _And<is_nothrow_move_assignable<_Tp>...>::value) {
865 std::__memberwise_forward_assign(
866 *this, std::move(__tuple), __tuple_types<_Tp...>(), typename __make_tuple_indices<sizeof...(_Tp)>::type());
884 std::__memberwise_forward_assign(*this, std::move(__tuple), __type_list<_Tp...>(), __index_sequence_for<_Tp...>());
867885 return *this;
868886 }
869887
......@@ -873,7 +891,7 @@ public:
873891 int> = 0>
874892 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
875893 operator=(tuple<_Up...> const& __tuple) noexcept(_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value) {
876 std::__memberwise_copy_assign(*this, __tuple, typename __make_tuple_indices<sizeof...(_Tp)>::type());
894 std::__memberwise_copy_assign(*this, __tuple, __index_sequence_for<_Tp...>());
877895 return *this;
878896 }
879897
......@@ -882,8 +900,7 @@ public:
882900 int> = 0>
883901 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
884902 operator=(tuple<_Up...>&& __tuple) noexcept(_And<is_nothrow_assignable<_Tp&, _Up>...>::value) {
885 std::__memberwise_forward_assign(
886 *this, std::move(__tuple), __tuple_types<_Up...>(), typename __make_tuple_indices<sizeof...(_Tp)>::type());
903 std::__memberwise_forward_assign(*this, std::move(__tuple), __type_list<_Up...>(), __index_sequence_for<_Tp...>());
887904 return *this;
888905 }
889906
......@@ -892,7 +909,7 @@ public:
892909 enable_if_t< _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
893910 is_assignable<const _Tp&, const _UTypes&>...>::value>* = nullptr>
894911 _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(const tuple<_UTypes...>& __u) const {
895 std::__memberwise_copy_assign(*this, __u, typename __make_tuple_indices<sizeof...(_Tp)>::type());
912 std::__memberwise_copy_assign(*this, __u, index_sequence_for<_Tp...>());
896913 return *this;
897914 }
898915
......@@ -900,8 +917,7 @@ public:
900917 enable_if_t< _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
901918 is_assignable<const _Tp&, _UTypes>...>::value>* = nullptr>
902919 _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(tuple<_UTypes...>&& __u) const {
903 std::__memberwise_forward_assign(
904 *this, __u, __tuple_types<_UTypes...>(), typename __make_tuple_indices<sizeof...(_Tp)>::type());
920 std::__memberwise_forward_assign(*this, __u, __type_list<_UTypes...>(), index_sequence_for<_Tp...>());
905921 return *this;
906922 }
907923# endif // _LIBCPP_STD_VER >= 23
......@@ -967,7 +983,7 @@ public:
967983 __enable_if_t< _And< _BoolConstant<_Np == sizeof...(_Tp)>, is_assignable<_Tp&, _Up const&>... >::value, int> = 0>
968984 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
969985 operator=(array<_Up, _Np> const& __array) noexcept(_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value) {
970 std::__memberwise_copy_assign(*this, __array, typename __make_tuple_indices<sizeof...(_Tp)>::type());
986 std::__memberwise_copy_assign(*this, __array, __index_sequence_for<_Tp...>());
971987 return *this;
972988 }
973989
......@@ -979,10 +995,7 @@ public:
979995 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
980996 operator=(array<_Up, _Np>&& __array) noexcept(_And<is_nothrow_assignable<_Tp&, _Up>...>::value) {
981997 std::__memberwise_forward_assign(
982 *this,
983 std::move(__array),
984 __tuple_types<_If<true, _Up, _Tp>...>(),
985 typename __make_tuple_indices<sizeof...(_Tp)>::type());
998 *this, std::move(__array), __type_list<_If<true, _Up, _Tp>...>(), __index_sequence_for<_Tp...>());
986999 return *this;
9871000 }
9881001
......@@ -997,7 +1010,24 @@ public:
9971010 noexcept(__all<is_nothrow_swappable_v<const _Tp&>...>::value) {
9981011 __base_.swap(__t.__base_);
9991012 }
1000# endif // _LIBCPP_STD_VER >= 23
1013
1014 template <__tuple_like_no_tuple _UTuple>
1015# if _LIBCPP_STD_VER >= 26
1016 requires __can_tuple_compare_equal<tuple, _UTuple> && (sizeof...(_Tp) == tuple_size_v<_UTuple>)
1017# endif // _LIBCPP_STD_VER >= 26
1018 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const tuple& __x, const _UTuple& __y) {
1019 static_assert(sizeof...(_Tp) == tuple_size_v<_UTuple>, "Can't compare tuple-like values of different sizes");
1020 return std::__tuple_compare_equal<sizeof...(_Tp)>(__x, __y);
1021 }
1022
1023 template <__tuple_like_no_tuple _UTuple>
1024 requires(sizeof...(_Tp) == tuple_size_v<_UTuple>)
1025 _LIBCPP_HIDE_FROM_ABI friend constexpr __tuple_common_comparison_category<tuple, _UTuple>
1026 operator<=>(const tuple& __x, const _UTuple& __y) {
1027 return std::__tuple_compare_three_way<__tuple_common_comparison_category<tuple, _UTuple>>(
1028 __x, __y, index_sequence_for<_Tp...>{});
1029 }
1030# endif // _LIBCPP_STD_VER >= 23
10011031};
10021032
10031033_LIBCPP_DIAGNOSTIC_PUSH
......@@ -1019,6 +1049,21 @@ public:
10191049 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(tuple&) _NOEXCEPT {}
10201050# if _LIBCPP_STD_VER >= 23
10211051 _LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple&) const noexcept {}
1052
1053 template <__tuple_like_no_tuple _UTuple>
1054# if _LIBCPP_STD_VER >= 26
1055 requires(tuple_size_v<_UTuple> == 0)
1056# endif // _LIBCPP_STD_VER >= 26
1057 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const tuple&, const _UTuple&) {
1058 static_assert(tuple_size_v<_UTuple> == 0, "Can't compare tuple-like values of different sizes");
1059 return true;
1060 }
1061
1062 template <__tuple_like_no_tuple _UTuple>
1063 requires(tuple_size_v<_UTuple> == 0)
1064 _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering operator<=>(const tuple&, const _UTuple&) {
1065 return strong_ordering::equal;
1066 }
10221067# endif
10231068};
10241069_LIBCPP_DIAGNOSTIC_POP
......@@ -1068,28 +1113,32 @@ swap(const tuple<_Tp...>& __lhs,
10681113// get
10691114
10701115template <size_t _Ip, class... _Tp>
1071inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, tuple<_Tp...> >::type&
1116[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1117typename tuple_element<_Ip, tuple<_Tp...> >::type&
10721118get(tuple<_Tp...>& __t) _NOEXCEPT {
10731119 using type _LIBCPP_NODEBUG = typename tuple_element<_Ip, tuple<_Tp...> >::type;
10741120 return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
10751121}
10761122
10771123template <size_t _Ip, class... _Tp>
1078inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type&
1124[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
1125_LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type&
10791126get(const tuple<_Tp...>& __t) _NOEXCEPT {
10801127 using type _LIBCPP_NODEBUG = typename tuple_element<_Ip, tuple<_Tp...> >::type;
10811128 return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
10821129}
10831130
10841131template <size_t _Ip, class... _Tp>
1085inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, tuple<_Tp...> >::type&&
1132[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1133typename tuple_element<_Ip, tuple<_Tp...> >::type&&
10861134get(tuple<_Tp...>&& __t) _NOEXCEPT {
10871135 using type _LIBCPP_NODEBUG = typename tuple_element<_Ip, tuple<_Tp...> >::type;
10881136 return static_cast<type&&>(static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
10891137}
10901138
10911139template <size_t _Ip, class... _Tp>
1092inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type&&
1140[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
1141_LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type&&
10931142get(const tuple<_Tp...>&& __t) _NOEXCEPT {
10941143 using type _LIBCPP_NODEBUG = typename tuple_element<_Ip, tuple<_Tp...> >::type;
10951144 return static_cast<const type&&>(static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
......@@ -1098,22 +1147,22 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT {
10981147# if _LIBCPP_STD_VER >= 14
10991148
11001149template <class _T1, class... _Args>
1101inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(tuple<_Args...>& __tup) noexcept {
1150[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(tuple<_Args...>& __tup) noexcept {
11021151 return std::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
11031152}
11041153
11051154template <class _T1, class... _Args>
1106inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept {
1155[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept {
11071156 return std::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
11081157}
11091158
11101159template <class _T1, class... _Args>
1111inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept {
1160[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept {
11121161 return std::get<__find_exactly_one_t<_T1, _Args...>::value>(std::move(__tup));
11131162}
11141163
11151164template <class _T1, class... _Args>
1116inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept {
1165[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept {
11171166 return std::get<__find_exactly_one_t<_T1, _Args...>::value>(std::move(__tup));
11181167}
11191168
......@@ -1122,37 +1171,22 @@ inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(tuple<_Args...> const&& _
11221171// tie
11231172
11241173template <class... _Tp>
1125inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&...> tie(_Tp&... __t) _NOEXCEPT {
1174[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&...> tie(_Tp&... __t) _NOEXCEPT {
11261175 return tuple<_Tp&...>(__t...);
11271176}
11281177
11291178template <class... _Tp>
1130inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<__unwrap_ref_decay_t<_Tp>...>
1179[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<__unwrap_ref_decay_t<_Tp>...>
11311180make_tuple(_Tp&&... __t) {
11321181 return tuple<__unwrap_ref_decay_t<_Tp>...>(std::forward<_Tp>(__t)...);
11331182}
11341183
11351184template <class... _Tp>
1136inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&&...> forward_as_tuple(_Tp&&... __t) _NOEXCEPT {
1185[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&&...>
1186forward_as_tuple(_Tp&&... __t) _NOEXCEPT {
11371187 return tuple<_Tp&&...>(std::forward<_Tp>(__t)...);
11381188}
11391189
1140template <size_t _Ip>
1141struct __tuple_equal {
1142 template <class _Tp, class _Up>
1143 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __x, const _Up& __y) {
1144 return __tuple_equal<_Ip - 1>()(__x, __y) && std::get<_Ip - 1>(__x) == std::get<_Ip - 1>(__y);
1145 }
1146};
1147
1148template <>
1149struct __tuple_equal<0> {
1150 template <class _Tp, class _Up>
1151 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp&, const _Up&) {
1152 return true;
1153 }
1154};
1155
11561190template <class... _Tp, class... _Up>
11571191# if _LIBCPP_STD_VER >= 26
11581192 requires(__all<requires(const _Tp& __t, const _Up& __u) {
......@@ -1162,27 +1196,19 @@ template <class... _Tp, class... _Up>
11621196inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
11631197operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) {
11641198 static_assert(sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
1165 return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
1199 return std::__tuple_compare_equal<sizeof...(_Tp)>(__x, __y);
11661200}
11671201
11681202# if _LIBCPP_STD_VER >= 20
11691203
11701204// operator<=>
11711205
1172template <class... _Tp, class... _Up, size_t... _Is>
1173_LIBCPP_HIDE_FROM_ABI constexpr auto
1174__tuple_compare_three_way(const tuple<_Tp...>& __x, const tuple<_Up...>& __y, index_sequence<_Is...>) {
1175 common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> __result = strong_ordering::equal;
1176 static_cast<void>(
1177 ((__result = std::__synth_three_way(std::get<_Is>(__x), std::get<_Is>(__y)), __result != 0) || ...));
1178 return __result;
1179}
1180
11811206template <class... _Tp, class... _Up>
11821207 requires(sizeof...(_Tp) == sizeof...(_Up))
11831208_LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...>
11841209operator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) {
1185 return std::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{});
1210 return std::__tuple_compare_three_way<common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...>>(
1211 __x, __y, index_sequence_for<_Tp...>{});
11861212}
11871213
11881214# else // _LIBCPP_STD_VER >= 20
......@@ -1243,65 +1269,59 @@ operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) {
12431269
12441270// tuple_cat
12451271
1246template <class _Tp, class _Up>
1247struct __tuple_cat_type;
1272template <class... _Tuples>
1273struct __tuple_cat_return_impl;
12481274
1249template <class... _Ttypes, class... _Utypes>
1250struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> > {
1251 using type _LIBCPP_NODEBUG = tuple<_Ttypes..., _Utypes...>;
1275template <class... _Types>
1276struct __tuple_cat_return_impl<tuple<_Types...>> {
1277 using type _LIBCPP_NODEBUG = tuple<_Types...>;
12521278};
12531279
1254template <class _ResultTuple, bool _Is_Tuple0TupleLike, class... _Tuples>
1255struct __tuple_cat_return_1 {};
1280template <class... _Types0, class... _Types1, class... _Tuples>
1281struct __tuple_cat_return_impl<tuple<_Types0...>, tuple<_Types1...>, _Tuples...>
1282 : __tuple_cat_return_impl<tuple<_Types0..., _Types1...>, _Tuples...> {};
12561283
1257template <class... _Types, class _Tuple0>
1258struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0> {
1259 using type _LIBCPP_NODEBUG =
1260 typename __tuple_cat_type< tuple<_Types...>,
1261 typename __make_tuple_types<__remove_cvref_t<_Tuple0> >::type >::type;
1262};
1263
1264template <class... _Types, class _Tuple0, class _Tuple1, class... _Tuples>
1265struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
1266 : public __tuple_cat_return_1<
1267 typename __tuple_cat_type< tuple<_Types...>,
1268 typename __make_tuple_types<__remove_cvref_t<_Tuple0> >::type >::type,
1269 __tuple_like_ext<__libcpp_remove_reference_t<_Tuple1> >::value,
1270 _Tuple1,
1271 _Tuples...> {};
1284template <class... _Types0, class _Tp, class _Up, class... _Tuples>
1285struct __tuple_cat_return_impl<tuple<_Types0...>, pair<_Tp, _Up>, _Tuples...>
1286 : __tuple_cat_return_impl<tuple<_Types0..., _Tp, _Up>, _Tuples...> {};
12721287
1273template <class... _Tuples>
1274struct __tuple_cat_return;
1288template <class, class, class>
1289struct __tuple_cat_array;
12751290
1276template <class _Tuple0, class... _Tuples>
1277struct __tuple_cat_return<_Tuple0, _Tuples...>
1278 : public __tuple_cat_return_1<tuple<>,
1279 __tuple_like_ext<__libcpp_remove_reference_t<_Tuple0> >::value,
1280 _Tuple0,
1281 _Tuples...> {};
1291template <class... _Types, class _ValueT, size_t... _Indices>
1292struct __tuple_cat_array<tuple<_Types...>, _ValueT, __index_sequence<_Indices...>> {
1293 template <size_t>
1294 using __value_type _LIBCPP_NODEBUG = _ValueT;
12821295
1283template <>
1284struct __tuple_cat_return<> {
1285 using type _LIBCPP_NODEBUG = tuple<>;
1296 using type _LIBCPP_NODEBUG = tuple<_Types..., __value_type<_Indices>...>;
12861297};
12871298
1288inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<> tuple_cat() { return tuple<>(); }
1299template <class... _Types, class _ValueT, size_t _Np, class... _Tuples>
1300struct __tuple_cat_return_impl<tuple<_Types...>, array<_ValueT, _Np>, _Tuples...>
1301 : __tuple_cat_return_impl<typename __tuple_cat_array<tuple<_Types...>, _ValueT, __make_index_sequence<_Np>>::type,
1302 _Tuples...> {};
1303
1304template <class... _Tuples>
1305using __tuple_cat_return_t _LIBCPP_NODEBUG =
1306 typename __tuple_cat_return_impl<tuple<>, __remove_cvref_t<_Tuples>...>::type;
1307
1308[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<> tuple_cat() { return tuple<>(); }
12891309
12901310template <class _Rp, class _Indices, class _Tuple0, class... _Tuples>
12911311struct __tuple_cat_return_ref_imp;
12921312
12931313template <class... _Types, size_t... _I0, class _Tuple0>
1294struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0> {
1314struct __tuple_cat_return_ref_imp<tuple<_Types...>, __index_sequence<_I0...>, _Tuple0> {
12951315 using _T0 _LIBCPP_NODEBUG = __libcpp_remove_reference_t<_Tuple0>;
12961316 typedef tuple<_Types..., __copy_cvref_t<_Tuple0, typename tuple_element<_I0, _T0>::type>&&...> type;
12971317};
12981318
12991319template <class... _Types, size_t... _I0, class _Tuple0, class _Tuple1, class... _Tuples>
1300struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0, _Tuple1, _Tuples...>
1320struct __tuple_cat_return_ref_imp<tuple<_Types...>, __index_sequence<_I0...>, _Tuple0, _Tuple1, _Tuples...>
13011321 : public __tuple_cat_return_ref_imp<
13021322 tuple<_Types...,
13031323 __copy_cvref_t<_Tuple0, typename tuple_element<_I0, __libcpp_remove_reference_t<_Tuple0>>::type>&&...>,
1304 typename __make_tuple_indices<tuple_size<__libcpp_remove_reference_t<_Tuple1> >::value>::type,
1324 __make_index_sequence<tuple_size<__libcpp_remove_reference_t<_Tuple1> >::value>,
13051325 _Tuple1,
13061326 _Tuples...> {};
13071327
......@@ -1309,7 +1329,7 @@ template <class _Tuple0, class... _Tuples>
13091329struct __tuple_cat_return_ref
13101330 : public __tuple_cat_return_ref_imp<
13111331 tuple<>,
1312 typename __make_tuple_indices< tuple_size<__libcpp_remove_reference_t<_Tuple0> >::value >::type,
1332 __make_index_sequence< tuple_size<__libcpp_remove_reference_t<_Tuple0> >::value >,
13131333 _Tuple0,
13141334 _Tuples...> {};
13151335
......@@ -1317,7 +1337,7 @@ template <class _Types, class _I0, class _J0>
13171337struct __tuple_cat;
13181338
13191339template <class... _Types, size_t... _I0, size_t... _J0>
1320struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> > {
1340struct __tuple_cat<tuple<_Types...>, __index_sequence<_I0...>, __index_sequence<_J0...>> {
13211341 template <class _Tuple0>
13221342 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
13231343 typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
......@@ -1335,8 +1355,8 @@ struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J
13351355 using _T0 _LIBCPP_NODEBUG = __libcpp_remove_reference_t<_Tuple0>;
13361356 using _T1 _LIBCPP_NODEBUG = __libcpp_remove_reference_t<_Tuple1>;
13371357 return __tuple_cat<tuple<_Types..., __copy_cvref_t<_Tuple0, typename tuple_element<_J0, _T0>::type>&&...>,
1338 typename __make_tuple_indices<sizeof...(_Types) + tuple_size<_T0>::value>::type,
1339 typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1358 __make_index_sequence<sizeof...(_Types) + tuple_size<_T0>::value>,
1359 __make_index_sequence<tuple_size<_T1>::value>>()(
13401360 std::forward_as_tuple(
13411361 std::forward<_Types>(std::get<_I0>(__t))..., std::get<_J0>(std::forward<_Tuple0>(__t0))...),
13421362 std::forward<_Tuple1>(__t1),
......@@ -1346,21 +1366,21 @@ struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J
13461366
13471367template <class _TupleDst, class _TupleSrc, size_t... _Indices>
13481368inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _TupleDst
1349__tuple_cat_select_element_wise(_TupleSrc&& __src, __tuple_indices<_Indices...>) {
1369__tuple_cat_select_element_wise(_TupleSrc&& __src, __index_sequence<_Indices...>) {
13501370 static_assert(tuple_size<_TupleDst>::value == tuple_size<_TupleSrc>::value,
13511371 "misuse of __tuple_cat_select_element_wise with tuples of different sizes");
13521372 return _TupleDst(std::get<_Indices>(std::forward<_TupleSrc>(__src))...);
13531373}
13541374
13551375template <class _Tuple0, class... _Tuples>
1356inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __tuple_cat_return<_Tuple0, _Tuples...>::type
1376[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __tuple_cat_return_t<_Tuple0, _Tuples...>
13571377tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls) {
13581378 using _T0 _LIBCPP_NODEBUG = __libcpp_remove_reference_t<_Tuple0>;
1359 using _TRet _LIBCPP_NODEBUG = typename __tuple_cat_return<_Tuple0, _Tuples...>::type;
1360 using _T0Indices _LIBCPP_NODEBUG = typename __make_tuple_indices<tuple_size<_T0>::value>::type;
1361 using _TRetIndices _LIBCPP_NODEBUG = typename __make_tuple_indices<tuple_size<_TRet>::value>::type;
1379 using _TRet _LIBCPP_NODEBUG = __tuple_cat_return_t<_Tuple0, _Tuples...>;
1380 using _T0Indices _LIBCPP_NODEBUG = __make_index_sequence<tuple_size<_T0>::value>;
1381 using _TRetIndices _LIBCPP_NODEBUG = __make_index_sequence<tuple_size<_TRet>::value>;
13621382 return std::__tuple_cat_select_element_wise<_TRet>(
1363 __tuple_cat<tuple<>, __tuple_indices<>, _T0Indices>()(
1383 __tuple_cat<tuple<>, __index_sequence<>, _T0Indices>()(
13641384 tuple<>(), std::forward<_Tuple0>(__t0), std::forward<_Tuples>(__tpls)...),
13651385 _TRetIndices());
13661386}
......@@ -1376,7 +1396,7 @@ struct uses_allocator<tuple<_Tp...>, _Alloc> : true_type {};
13761396// clang-format off
13771397template <class _Fn, class _Tuple, size_t... _Id>
13781398inline _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto)
1379__apply_tuple_impl(_Fn&& __f, _Tuple&& __t, __tuple_indices<_Id...>)
1399__apply_tuple_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Id...>)
13801400 _LIBCPP_NOEXCEPT_RETURN(std::__invoke(std::forward<_Fn>(__f), std::get<_Id>(std::forward<_Tuple>(__t))...))
13811401
13821402template <class _Fn, class _Tuple>
......@@ -1384,28 +1404,29 @@ inline _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) apply(_Fn&& __f, _Tuple&&
13841404 _LIBCPP_NOEXCEPT_RETURN(std::__apply_tuple_impl(
13851405 std::forward<_Fn>(__f),
13861406 std::forward<_Tuple>(__t),
1387 typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{}))
1407 make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>()))
13881408
13891409#if _LIBCPP_STD_VER >= 20
13901410template <class _Tp, class _Tuple, size_t... _Idx>
1391inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
1411inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
13921412 noexcept(noexcept(_Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...)))
13931413 requires is_constructible_v<_Tp, decltype(std::get<_Idx>(std::forward<_Tuple>(__t)))...> {
13941414 return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...);
13951415}
13961416#else
13971417template <class _Tp, class _Tuple, size_t... _Idx>
1398inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>,
1418inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>,
13991419 enable_if_t<is_constructible_v<_Tp, decltype(std::get<_Idx>(std::forward<_Tuple>(__t)))...>> * = nullptr)
14001420 _LIBCPP_NOEXCEPT_RETURN(_Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...))
14011421#endif // _LIBCPP_STD_VER >= 20
1422#undef _LIBCPP_NOEXCEPT_RETURN
14021423
14031424template <class _Tp, class _Tuple,
1404 class _Seq = typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type, class = void>
1425 class _Seq = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>, class = void>
14051426inline constexpr bool __can_make_from_tuple = false;
14061427
14071428template <class _Tp, class _Tuple, size_t... _Idx>
1408inline constexpr bool __can_make_from_tuple<_Tp, _Tuple, __tuple_indices<_Idx...>,
1429inline constexpr bool __can_make_from_tuple<_Tp, _Tuple, index_sequence<_Idx...>,
14091430 enable_if_t<is_constructible_v<_Tp, decltype(std::get<_Idx>(std::declval<_Tuple>()))...>>> = true;
14101431
14111432// Based on LWG3528(https://wg21.link/LWG3528) and http://eel.is/c++draft/description#structure.requirements-9,
......@@ -1418,10 +1439,19 @@ template <class _Tp, class _Tuple>
14181439#else
14191440template <class _Tp, class _Tuple, class = enable_if_t<__can_make_from_tuple<_Tp, _Tuple>>> // strengthen
14201441#endif // _LIBCPP_STD_VER >= 20
1421inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp make_from_tuple(_Tuple&& __t)
1422 _LIBCPP_NOEXCEPT_RETURN(std::__make_from_tuple_impl<_Tp>(
1423 std::forward<_Tuple>(__t), typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{}))
1424# undef _LIBCPP_NOEXCEPT_RETURN
1442
1443[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp make_from_tuple(_Tuple&& __t)
1444 noexcept(noexcept(std::__make_from_tuple_impl<_Tp>(std::forward<_Tuple>(__t),
1445 make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>()))) {
1446#if _LIBCPP_STD_VER >= 23
1447 if constexpr (tuple_size_v<remove_reference_t<_Tuple>> == 1) {
1448 static_assert(!std::reference_constructs_from_temporary_v<_Tp, decltype(std::get<0>(std::declval<_Tuple>()))>,
1449 "Attempted construction of reference element binds to a temporary whose lifetime has ended");
1450 }
1451#endif // _LIBCPP_STD_VER >= 23
1452 return std::__make_from_tuple_impl<_Tp>(
1453 std::forward<_Tuple>(__t), make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>());
1454}
14251455
14261456# endif // _LIBCPP_STD_VER >= 17
14271457
lib/libcxx/include/type_traits+8-2
......@@ -454,6 +454,10 @@ namespace std
454454 template<class B> inline constexpr bool negation_v
455455 = negation<B>::value; // since C++17
456456
457 // [meta.const.eval], constant evaluation context
458 constexpr bool is_constant_evaluated() noexcept; // C++20
459 template<class T>
460 consteval bool is_within_lifetime(const T*) noexcept; // C++26
457461}
458462
459463*/
......@@ -546,9 +550,7 @@ namespace std
546550
547551# if _LIBCPP_STD_VER >= 20
548552# include <__type_traits/common_reference.h>
549# include <__type_traits/is_bounded_array.h>
550553# include <__type_traits/is_constant_evaluated.h>
551# include <__type_traits/is_unbounded_array.h>
552554# include <__type_traits/type_identity.h>
553555# include <__type_traits/unwrap_ref.h>
554556# endif
......@@ -559,6 +561,10 @@ namespace std
559561# include <__type_traits/reference_converts_from_temporary.h>
560562# endif
561563
564# if _LIBCPP_STD_VER >= 26
565# include <__type_traits/is_within_lifetime.h>
566# endif
567
562568# include <version>
563569
564570# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
lib/libcxx/include/typeindex+5-3
......@@ -86,8 +86,8 @@ public:
8686 }
8787# endif
8888
89 _LIBCPP_HIDE_FROM_ABI size_t hash_code() const _NOEXCEPT { return __t_->hash_code(); }
90 _LIBCPP_HIDE_FROM_ABI const char* name() const _NOEXCEPT { return __t_->name(); }
89 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t hash_code() const _NOEXCEPT { return __t_->hash_code(); }
90 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const char* name() const _NOEXCEPT { return __t_->name(); }
9191};
9292
9393template <class _Tp>
......@@ -95,7 +95,9 @@ struct hash;
9595
9696template <>
9797struct hash<type_index> : public __unary_function<type_index, size_t> {
98 _LIBCPP_HIDE_FROM_ABI size_t operator()(type_index __index) const _NOEXCEPT { return __index.hash_code(); }
98 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(type_index __index) const _NOEXCEPT {
99 return __index.hash_code();
100 }
99101};
100102
101103_LIBCPP_END_NAMESPACE_STD
lib/libcxx/include/typeinfo+92-89
......@@ -95,11 +95,13 @@ class _LIBCPP_EXPORTED_FROM_ABI type_info {
9595public:
9696 virtual ~type_info();
9797
98 const char* name() const _NOEXCEPT;
98 [[__nodiscard__]] const char* name() const _NOEXCEPT;
9999
100 _LIBCPP_HIDE_FROM_ABI bool before(const type_info& __arg) const _NOEXCEPT { return __compare(__arg) < 0; }
100 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool before(const type_info& __arg) const _NOEXCEPT {
101 return __compare(__arg) < 0;
102 }
101103
102 size_t hash_code() const _NOEXCEPT;
104 [[__nodiscard__]] size_t hash_code() const _NOEXCEPT;
103105
104106 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const type_info& __arg) const _NOEXCEPT {
105107 // When evaluated in a constant expression, both type infos simply can't come
......@@ -186,99 +188,99 @@ public:
186188# endif
187189# endif
188190
189struct __type_info_implementations {
190 struct __string_impl_base {
191 typedef const char* __type_name_t;
192 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR static const char*
193 __type_name_to_string(__type_name_t __v) _NOEXCEPT {
194 return __v;
195 }
196 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR static __type_name_t
197 __string_to_type_name(const char* __v) _NOEXCEPT {
198 return __v;
199 }
200 };
191namespace __type_info_implementations {
192struct __string_impl_base {
193 typedef const char* __type_name_t;
194 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR static const char*
195 __type_name_to_string(__type_name_t __v) _NOEXCEPT {
196 return __v;
197 }
198 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR static __type_name_t
199 __string_to_type_name(const char* __v) _NOEXCEPT {
200 return __v;
201 }
202};
201203
202 struct __unique_impl : __string_impl_base {
203 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static size_t __hash(__type_name_t __v) _NOEXCEPT {
204 return reinterpret_cast<size_t>(__v);
205 }
206 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
207 return __lhs == __rhs;
208 }
209 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
210 return __lhs < __rhs;
211 }
212 };
213
214 struct __non_unique_impl : __string_impl_base {
215 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static size_t __hash(__type_name_t __ptr) _NOEXCEPT {
216 size_t __hash = 5381;
217 while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
218 __hash = (__hash * 33) ^ __c;
219 return __hash;
220 }
221 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
222 return __lhs == __rhs || __builtin_strcmp(__lhs, __rhs) == 0;
223 }
224 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
225 return __builtin_strcmp(__lhs, __rhs) < 0;
226 }
227 };
204struct __unique_impl : __string_impl_base {
205 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static size_t __hash(__type_name_t __v) _NOEXCEPT {
206 return reinterpret_cast<size_t>(__v);
207 }
208 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
209 return __lhs == __rhs;
210 }
211 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
212 return __lhs < __rhs;
213 }
214};
228215
229 struct __non_unique_arm_rtti_bit_impl {
230 typedef uintptr_t __type_name_t;
216struct __non_unique_impl : __string_impl_base {
217 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static size_t __hash(__type_name_t __ptr) _NOEXCEPT {
218 size_t __hash = 5381;
219 while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
220 __hash = (__hash * 33) ^ __c;
221 return __hash;
222 }
223 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
224 return __lhs == __rhs || __builtin_strcmp(__lhs, __rhs) == 0;
225 }
226 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
227 return __builtin_strcmp(__lhs, __rhs) < 0;
228 }
229};
231230
232 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static const char* __type_name_to_string(__type_name_t __v) _NOEXCEPT {
233 return reinterpret_cast<const char*>(__v & ~__non_unique_rtti_bit::value);
234 }
235 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static __type_name_t __string_to_type_name(const char* __v) _NOEXCEPT {
236 return reinterpret_cast<__type_name_t>(__v);
237 }
231struct __non_unique_arm_rtti_bit_impl {
232 typedef uintptr_t __type_name_t;
238233
239 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static size_t __hash(__type_name_t __v) _NOEXCEPT {
240 if (__is_type_name_unique(__v))
241 return __v;
242 return __non_unique_impl::__hash(__type_name_to_string(__v));
243 }
244 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
245 if (__lhs == __rhs)
246 return true;
247 if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs))
248 // Either both are unique and have a different address, or one of them
249 // is unique and the other one isn't. In both cases they are unequal.
250 return false;
251 return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) == 0;
252 }
253 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
254 if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs))
255 return __lhs < __rhs;
256 return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) < 0;
257 }
234 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static const char* __type_name_to_string(__type_name_t __v) _NOEXCEPT {
235 return reinterpret_cast<const char*>(__v & ~__non_unique_rtti_bit::value);
236 }
237 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static __type_name_t __string_to_type_name(const char* __v) _NOEXCEPT {
238 return reinterpret_cast<__type_name_t>(__v);
239 }
258240
259 private:
260 // The unique bit is the top bit. It is expected that __type_name_t is 64 bits when
261 // this implementation is actually used.
262 typedef integral_constant<__type_name_t, (1ULL << ((__CHAR_BIT__ * sizeof(__type_name_t)) - 1))>
263 __non_unique_rtti_bit;
241 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static size_t __hash(__type_name_t __v) _NOEXCEPT {
242 if (__is_type_name_unique(__v))
243 return __v;
244 return __non_unique_impl::__hash(__type_name_to_string(__v));
245 }
246 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
247 if (__lhs == __rhs)
248 return true;
249 if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs))
250 // Either both are unique and have a different address, or one of them
251 // is unique and the other one isn't. In both cases they are unequal.
252 return false;
253 return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) == 0;
254 }
255 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
256 if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs))
257 return __lhs < __rhs;
258 return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) < 0;
259 }
264260
265 _LIBCPP_HIDE_FROM_ABI static bool __is_type_name_unique(__type_name_t __lhs) _NOEXCEPT {
266 return !(__lhs & __non_unique_rtti_bit::value);
267 }
268 };
261private:
262 // The unique bit is the top bit. It is expected that __type_name_t is 64 bits when
263 // this implementation is actually used.
264 typedef integral_constant<__type_name_t, (1ULL << ((__CHAR_BIT__ * sizeof(__type_name_t)) - 1))>
265 __non_unique_rtti_bit;
266
267 _LIBCPP_HIDE_FROM_ABI static bool __is_type_name_unique(__type_name_t __lhs) _NOEXCEPT {
268 return !(__lhs & __non_unique_rtti_bit::value);
269 }
270};
269271
270 typedef
272typedef
271273# if _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 1
272 __unique_impl
274 __unique_impl
273275# elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 2
274 __non_unique_impl
276 __non_unique_impl
275277# elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 3
276 __non_unique_arm_rtti_bit_impl
278 __non_unique_arm_rtti_bit_impl
277279# else
278280# error invalid configuration for _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION
279281# endif
280 __impl;
281};
282 __impl;
283} // namespace __type_info_implementations
282284
283285# if __has_cpp_attribute(_Clang::__ptrauth_vtable_pointer__)
284286# if __has_feature(ptrauth_type_info_vtable_pointer_discrimination)
......@@ -306,14 +308,15 @@ protected:
306308
307309public:
308310 virtual ~type_info();
311 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const char* name() const _NOEXCEPT {
312 return __impl::__type_name_to_string(__type_name);
313 }
309314
310 _LIBCPP_HIDE_FROM_ABI const char* name() const _NOEXCEPT { return __impl::__type_name_to_string(__type_name); }
311
312 _LIBCPP_HIDE_FROM_ABI bool before(const type_info& __arg) const _NOEXCEPT {
315 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool before(const type_info& __arg) const _NOEXCEPT {
313316 return __impl::__lt(__type_name, __arg.__type_name);
314317 }
315318
316 _LIBCPP_HIDE_FROM_ABI size_t hash_code() const _NOEXCEPT { return __impl::__hash(__type_name); }
319 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t hash_code() const _NOEXCEPT { return __impl::__hash(__type_name); }
317320
318321 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const type_info& __arg) const _NOEXCEPT {
319322 // When evaluated in a constant expression, both type infos simply can't come
......@@ -336,7 +339,7 @@ public:
336339 _LIBCPP_HIDE_FROM_ABI bad_cast(const bad_cast&) _NOEXCEPT = default;
337340 _LIBCPP_HIDE_FROM_ABI bad_cast& operator=(const bad_cast&) _NOEXCEPT = default;
338341 ~bad_cast() _NOEXCEPT override;
339 const char* what() const _NOEXCEPT override;
342 [[__nodiscard__]] const char* what() const _NOEXCEPT override;
340343};
341344
342345class _LIBCPP_EXPORTED_FROM_ABI bad_typeid : public exception {
......@@ -345,7 +348,7 @@ public:
345348 _LIBCPP_HIDE_FROM_ABI bad_typeid(const bad_typeid&) _NOEXCEPT = default;
346349 _LIBCPP_HIDE_FROM_ABI bad_typeid& operator=(const bad_typeid&) _NOEXCEPT = default;
347350 ~bad_typeid() _NOEXCEPT override;
348 const char* what() const _NOEXCEPT override;
351 [[__nodiscard__]] const char* what() const _NOEXCEPT override;
349352};
350353
351354} // namespace std
lib/libcxx/include/unordered_map+179-304
......@@ -600,6 +600,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
600600# include <__memory/addressof.h>
601601# include <__memory/allocator.h>
602602# include <__memory/allocator_traits.h>
603# include <__memory/compressed_pair.h>
603604# include <__memory/pointer_traits.h>
604605# include <__memory/unique_ptr.h>
605606# include <__memory_resource/polymorphic_allocator.h>
......@@ -643,34 +644,9 @@ _LIBCPP_PUSH_MACROS
643644
644645_LIBCPP_BEGIN_NAMESPACE_STD
645646
646template <class _Key,
647 class _Cp,
648 class _Hash,
649 class _Pred,
650 bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value>
651class __unordered_map_hasher : private _Hash {
652public:
653 _LIBCPP_HIDE_FROM_ABI __unordered_map_hasher() _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value) : _Hash() {}
654 _LIBCPP_HIDE_FROM_ABI __unordered_map_hasher(const _Hash& __h) _NOEXCEPT_(is_nothrow_copy_constructible<_Hash>::value)
655 : _Hash(__h) {}
656 _LIBCPP_HIDE_FROM_ABI const _Hash& hash_function() const _NOEXCEPT { return *this; }
657 _LIBCPP_HIDE_FROM_ABI size_t operator()(const _Cp& __x) const { return static_cast<const _Hash&>(*this)(__x.first); }
658 _LIBCPP_HIDE_FROM_ABI size_t operator()(const _Key& __x) const { return static_cast<const _Hash&>(*this)(__x); }
659# if _LIBCPP_STD_VER >= 20
660 template <typename _K2>
661 _LIBCPP_HIDE_FROM_ABI size_t operator()(const _K2& __x) const {
662 return static_cast<const _Hash&>(*this)(__x);
663 }
664# endif
665 _LIBCPP_HIDE_FROM_ABI void swap(__unordered_map_hasher& __y) _NOEXCEPT_(__is_nothrow_swappable_v<_Hash>) {
666 using std::swap;
667 swap(static_cast<_Hash&>(*this), static_cast<_Hash&>(__y));
668 }
669};
670
671647template <class _Key, class _Cp, class _Hash, class _Pred>
672class __unordered_map_hasher<_Key, _Cp, _Hash, _Pred, false> {
673 _Hash __hash_;
648class __unordered_map_hasher {
649 _LIBCPP_COMPRESSED_ELEMENT(_Hash, __hash_);
674650
675651public:
676652 _LIBCPP_HIDE_FROM_ABI __unordered_map_hasher() _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value)
......@@ -692,60 +668,16 @@ public:
692668 }
693669};
694670
695template <class _Key, class _Cp, class _Hash, class _Pred, bool __b>
671template <class _Key, class _Cp, class _Hash, class _Pred>
696672inline _LIBCPP_HIDE_FROM_ABI void
697swap(__unordered_map_hasher<_Key, _Cp, _Hash, _Pred, __b>& __x,
698 __unordered_map_hasher<_Key, _Cp, _Hash, _Pred, __b>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
673swap(__unordered_map_hasher<_Key, _Cp, _Hash, _Pred>& __x, __unordered_map_hasher<_Key, _Cp, _Hash, _Pred>& __y)
674 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
699675 __x.swap(__y);
700676}
701677
702template <class _Key,
703 class _Cp,
704 class _Pred,
705 class _Hash,
706 bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value>
707class __unordered_map_equal : private _Pred {
708public:
709 _LIBCPP_HIDE_FROM_ABI __unordered_map_equal() _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value) : _Pred() {}
710 _LIBCPP_HIDE_FROM_ABI __unordered_map_equal(const _Pred& __p) _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value)
711 : _Pred(__p) {}
712 _LIBCPP_HIDE_FROM_ABI const _Pred& key_eq() const _NOEXCEPT { return *this; }
713 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Cp& __x, const _Cp& __y) const {
714 return static_cast<const _Pred&>(*this)(__x.first, __y.first);
715 }
716 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Cp& __x, const _Key& __y) const {
717 return static_cast<const _Pred&>(*this)(__x.first, __y);
718 }
719 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _Cp& __y) const {
720 return static_cast<const _Pred&>(*this)(__x, __y.__get_value().first);
721 }
722# if _LIBCPP_STD_VER >= 20
723 template <typename _K2>
724 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Cp& __x, const _K2& __y) const {
725 return static_cast<const _Pred&>(*this)(__x.first, __y);
726 }
727 template <typename _K2>
728 _LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _Cp& __y) const {
729 return static_cast<const _Pred&>(*this)(__x, __y.__get_value().first);
730 }
731 template <typename _K2>
732 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _K2& __y) const {
733 return static_cast<const _Pred&>(*this)(__x, __y);
734 }
735 template <typename _K2>
736 _LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _Key& __y) const {
737 return static_cast<const _Pred&>(*this)(__x, __y);
738 }
739# endif
740 _LIBCPP_HIDE_FROM_ABI void swap(__unordered_map_equal& __y) _NOEXCEPT_(__is_nothrow_swappable_v<_Pred>) {
741 using std::swap;
742 swap(static_cast<_Pred&>(*this), static_cast<_Pred&>(__y));
743 }
744};
745
746678template <class _Key, class _Cp, class _Pred, class _Hash>
747class __unordered_map_equal<_Key, _Cp, _Pred, _Hash, false> {
748 _Pred __pred_;
679class __unordered_map_equal {
680 _LIBCPP_COMPRESSED_ELEMENT(_Pred, __pred_);
749681
750682public:
751683 _LIBCPP_HIDE_FROM_ABI __unordered_map_equal() _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value)
......@@ -780,9 +712,9 @@ public:
780712 }
781713};
782714
783template <class _Key, class _Cp, class _Pred, class _Hash, bool __b>
715template <class _Key, class _Cp, class _Pred, class _Hash>
784716inline _LIBCPP_HIDE_FROM_ABI void
785swap(__unordered_map_equal<_Key, _Cp, _Pred, _Hash, __b>& __x, __unordered_map_equal<_Key, _Cp, _Pred, _Hash, __b>& __y)
717swap(__unordered_map_equal<_Key, _Cp, _Pred, _Hash>& __x, __unordered_map_equal<_Key, _Cp, _Pred, _Hash>& __y)
786718 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
787719 __x.swap(__y);
788720}
......@@ -844,10 +776,10 @@ class __hash_map_iterator {
844776
845777public:
846778 typedef forward_iterator_tag iterator_category;
847 typedef typename _NodeTypes::__map_value_type value_type;
848 typedef typename _NodeTypes::difference_type difference_type;
779 using value_type = typename _HashIterator::value_type;
780 using difference_type = ptrdiff_t;
849781 typedef value_type& reference;
850 typedef typename _NodeTypes::__map_value_type_pointer pointer;
782 using pointer = typename _HashIterator::pointer;
851783
852784 _LIBCPP_HIDE_FROM_ABI __hash_map_iterator() _NOEXCEPT {}
853785
......@@ -895,10 +827,10 @@ class __hash_map_const_iterator {
895827
896828public:
897829 typedef forward_iterator_tag iterator_category;
898 typedef typename _NodeTypes::__map_value_type value_type;
899 typedef typename _NodeTypes::difference_type difference_type;
830 using value_type = typename _HashIterator::value_type;
831 using difference_type = ptrdiff_t;
900832 typedef const value_type& reference;
901 typedef typename _NodeTypes::__const_map_value_type_pointer pointer;
833 using pointer = typename _HashIterator::pointer;
902834
903835 _LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator() _NOEXCEPT {}
904836
......@@ -972,9 +904,6 @@ private:
972904
973905 __table __table_;
974906
975 typedef typename __table::_NodeTypes _NodeTypes;
976 typedef typename __table::__node_pointer __node_pointer;
977 typedef typename __table::__node_const_pointer __node_const_pointer;
978907 typedef typename __table::__node_traits __node_traits;
979908 typedef typename __table::__node_allocator __node_allocator;
980909 typedef typename __table::__node __node;
......@@ -1046,10 +975,10 @@ public:
1046975# endif
1047976
1048977 _LIBCPP_HIDE_FROM_ABI explicit unordered_map(const allocator_type& __a);
1049 _LIBCPP_HIDE_FROM_ABI unordered_map(const unordered_map& __u);
978 _LIBCPP_HIDE_FROM_ABI unordered_map(const unordered_map& __u) = default;
1050979 _LIBCPP_HIDE_FROM_ABI unordered_map(const unordered_map& __u, const allocator_type& __a);
1051980# ifndef _LIBCPP_CXX03_LANG
1052 _LIBCPP_HIDE_FROM_ABI unordered_map(unordered_map&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
981 _LIBCPP_HIDE_FROM_ABI unordered_map(unordered_map&& __u) = default;
1053982 _LIBCPP_HIDE_FROM_ABI unordered_map(unordered_map&& __u, const allocator_type& __a);
1054983 _LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list<value_type> __il);
1055984 _LIBCPP_HIDE_FROM_ABI
......@@ -1099,41 +1028,26 @@ public:
10991028 static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), "");
11001029 }
11011030
1102 _LIBCPP_HIDE_FROM_ABI unordered_map& operator=(const unordered_map& __u) {
1103# ifndef _LIBCPP_CXX03_LANG
1104 __table_ = __u.__table_;
1105# else
1106 if (this != std::addressof(__u)) {
1107 __table_.clear();
1108 __table_.hash_function() = __u.__table_.hash_function();
1109 __table_.key_eq() = __u.__table_.key_eq();
1110 __table_.max_load_factor() = __u.__table_.max_load_factor();
1111 __table_.__copy_assign_alloc(__u.__table_);
1112 insert(__u.begin(), __u.end());
1113 }
1114# endif
1115 return *this;
1116 }
1031 _LIBCPP_HIDE_FROM_ABI unordered_map& operator=(const unordered_map& __u) = default;
11171032# ifndef _LIBCPP_CXX03_LANG
1118 _LIBCPP_HIDE_FROM_ABI unordered_map& operator=(unordered_map&& __u)
1119 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
1033 _LIBCPP_HIDE_FROM_ABI unordered_map& operator=(unordered_map&& __u) = default;
11201034 _LIBCPP_HIDE_FROM_ABI unordered_map& operator=(initializer_list<value_type> __il);
11211035# endif // _LIBCPP_CXX03_LANG
11221036
1123 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
1037 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
11241038 return allocator_type(__table_.__node_alloc());
11251039 }
11261040
11271041 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __table_.size() == 0; }
1128 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __table_.size(); }
1129 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __table_.max_size(); }
1042 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __table_.size(); }
1043 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __table_.max_size(); }
11301044
1131 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __table_.begin(); }
1132 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __table_.end(); }
1133 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __table_.begin(); }
1134 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __table_.end(); }
1135 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __table_.begin(); }
1136 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __table_.end(); }
1045 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __table_.begin(); }
1046 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __table_.end(); }
1047 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __table_.begin(); }
1048 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __table_.end(); }
1049 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __table_.begin(); }
1050 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __table_.end(); }
11371051
11381052 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __x) { return __table_.__emplace_unique(__x); }
11391053
......@@ -1187,14 +1101,13 @@ public:
11871101# if _LIBCPP_STD_VER >= 17
11881102 template <class... _Args>
11891103 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args) {
1190 return __table_.__emplace_unique_key_args(
1191 __k, piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple(std::forward<_Args>(__args)...));
1104 return __table_.__emplace_unique(
1105 piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple(std::forward<_Args>(__args)...));
11921106 }
11931107
11941108 template <class... _Args>
11951109 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args) {
1196 return __table_.__emplace_unique_key_args(
1197 __k,
1110 return __table_.__emplace_unique(
11981111 piecewise_construct,
11991112 std::forward_as_tuple(std::move(__k)),
12001113 std::forward_as_tuple(std::forward<_Args>(__args)...));
......@@ -1212,7 +1125,7 @@ public:
12121125
12131126 template <class _Vp>
12141127 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v) {
1215 pair<iterator, bool> __res = __table_.__emplace_unique_key_args(__k, __k, std::forward<_Vp>(__v));
1128 pair<iterator, bool> __res = __table_.__emplace_unique(__k, std::forward<_Vp>(__v));
12161129 if (!__res.second) {
12171130 __res.first->second = std::forward<_Vp>(__v);
12181131 }
......@@ -1221,7 +1134,7 @@ public:
12211134
12221135 template <class _Vp>
12231136 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v) {
1224 pair<iterator, bool> __res = __table_.__emplace_unique_key_args(__k, std::move(__k), std::forward<_Vp>(__v));
1137 pair<iterator, bool> __res = __table_.__emplace_unique(std::move(__k), std::forward<_Vp>(__v));
12251138 if (!__res.second) {
12261139 __res.first->second = std::forward<_Vp>(__v);
12271140 }
......@@ -1258,10 +1171,10 @@ public:
12581171 "node_type with incompatible allocator passed to unordered_map::insert()");
12591172 return __table_.template __node_handle_insert_unique<node_type>(__hint.__i_, std::move(__nh));
12601173 }
1261 _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
1174 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
12621175 return __table_.template __node_handle_extract<node_type>(__key);
12631176 }
1264 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
1177 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
12651178 return __table_.template __node_handle_extract<node_type>(__it.__i_);
12661179 }
12671180
......@@ -1295,52 +1208,56 @@ public:
12951208 __table_.swap(__u.__table_);
12961209 }
12971210
1298 _LIBCPP_HIDE_FROM_ABI hasher hash_function() const { return __table_.hash_function().hash_function(); }
1299 _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq().key_eq(); }
1211 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI hasher hash_function() const {
1212 return __table_.hash_function().hash_function();
1213 }
1214 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq().key_eq(); }
13001215
1301 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
1302 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
1216 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
1217 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
13031218# if _LIBCPP_STD_VER >= 20
13041219 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1305 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1220 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
13061221 return __table_.find(__k);
13071222 }
13081223 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1309 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1224 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
13101225 return __table_.find(__k);
13111226 }
13121227# endif // _LIBCPP_STD_VER >= 20
13131228
1314 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_unique(__k); }
1229 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const {
1230 return __table_.__count_unique(__k);
1231 }
13151232# if _LIBCPP_STD_VER >= 20
13161233 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1317 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1234 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
13181235 return __table_.__count_unique(__k);
13191236 }
13201237# endif // _LIBCPP_STD_VER >= 20
13211238
13221239# if _LIBCPP_STD_VER >= 20
1323 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1240 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
13241241
13251242 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1326 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1243 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
13271244 return find(__k) != end();
13281245 }
13291246# endif // _LIBCPP_STD_VER >= 20
13301247
1331 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
1248 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
13321249 return __table_.__equal_range_unique(__k);
13331250 }
1334 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
1251 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
13351252 return __table_.__equal_range_unique(__k);
13361253 }
13371254# if _LIBCPP_STD_VER >= 20
13381255 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1339 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
1256 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
13401257 return __table_.__equal_range_unique(__k);
13411258 }
13421259 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1343 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
1260 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
13441261 return __table_.__equal_range_unique(__k);
13451262 }
13461263# endif // _LIBCPP_STD_VER >= 20
......@@ -1350,24 +1267,32 @@ public:
13501267 _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k);
13511268# endif
13521269
1353 _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k);
1354 _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;
1270 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k);
1271 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;
13551272
1356 _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __table_.bucket_count(); }
1357 _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT { return __table_.max_bucket_count(); }
1273 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __table_.bucket_count(); }
1274 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT {
1275 return __table_.max_bucket_count();
1276 }
13581277
1359 _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const { return __table_.bucket_size(__n); }
1360 _LIBCPP_HIDE_FROM_ABI size_type bucket(const key_type& __k) const { return __table_.bucket(__k); }
1278 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const {
1279 return __table_.bucket_size(__n);
1280 }
1281 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket(const key_type& __k) const { return __table_.bucket(__k); }
13611282
1362 _LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { return __table_.begin(__n); }
1363 _LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { return __table_.end(__n); }
1364 _LIBCPP_HIDE_FROM_ABI const_local_iterator begin(size_type __n) const { return __table_.cbegin(__n); }
1365 _LIBCPP_HIDE_FROM_ABI const_local_iterator end(size_type __n) const { return __table_.cend(__n); }
1366 _LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const { return __table_.cbegin(__n); }
1367 _LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { return __table_.cend(__n); }
1283 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { return __table_.begin(__n); }
1284 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { return __table_.end(__n); }
1285 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator begin(size_type __n) const {
1286 return __table_.cbegin(__n);
1287 }
1288 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator end(size_type __n) const { return __table_.cend(__n); }
1289 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const {
1290 return __table_.cbegin(__n);
1291 }
1292 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { return __table_.cend(__n); }
13681293
1369 _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { return __table_.load_factor(); }
1370 _LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __table_.max_load_factor(); }
1294 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { return __table_.load_factor(); }
1295 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __table_.max_load_factor(); }
13711296 _LIBCPP_HIDE_FROM_ABI void max_load_factor(float __mlf) { __table_.max_load_factor(__mlf); }
13721297 _LIBCPP_HIDE_FROM_ABI void rehash(size_type __n) { __table_.__rehash_unique(__n); }
13731298 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n) { __table_.__reserve_unique(__n); }
......@@ -1384,10 +1309,10 @@ template <class _InputIterator,
13841309 class _Pred = equal_to<__iter_key_type<_InputIterator>>,
13851310 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
13861311 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1387 class = enable_if_t<!__is_allocator<_Hash>::value>,
1312 class = enable_if_t<!__is_allocator_v<_Hash>>,
13881313 class = enable_if_t<!is_integral<_Hash>::value>,
1389 class = enable_if_t<!__is_allocator<_Pred>::value>,
1390 class = enable_if_t<__is_allocator<_Allocator>::value>>
1314 class = enable_if_t<!__is_allocator_v<_Pred>>,
1315 class = enable_if_t<__is_allocator_v<_Allocator>>>
13911316unordered_map(_InputIterator,
13921317 _InputIterator,
13931318 typename allocator_traits<_Allocator>::size_type = 0,
......@@ -1401,10 +1326,10 @@ template <ranges::input_range _Range,
14011326 class _Hash = hash<__range_key_type<_Range>>,
14021327 class _Pred = equal_to<__range_key_type<_Range>>,
14031328 class _Allocator = allocator<__range_to_alloc_type<_Range>>,
1404 class = enable_if_t<!__is_allocator<_Hash>::value>,
1329 class = enable_if_t<!__is_allocator_v<_Hash>>,
14051330 class = enable_if_t<!is_integral<_Hash>::value>,
1406 class = enable_if_t<!__is_allocator<_Pred>::value>,
1407 class = enable_if_t<__is_allocator<_Allocator>::value>>
1331 class = enable_if_t<!__is_allocator_v<_Pred>>,
1332 class = enable_if_t<__is_allocator_v<_Allocator>>>
14081333unordered_map(from_range_t,
14091334 _Range&&,
14101335 typename allocator_traits<_Allocator>::size_type = 0,
......@@ -1419,10 +1344,10 @@ template <class _Key,
14191344 class _Hash = hash<remove_const_t<_Key>>,
14201345 class _Pred = equal_to<remove_const_t<_Key>>,
14211346 class _Allocator = allocator<pair<const _Key, _Tp>>,
1422 class = enable_if_t<!__is_allocator<_Hash>::value>,
1347 class = enable_if_t<!__is_allocator_v<_Hash>>,
14231348 class = enable_if_t<!is_integral<_Hash>::value>,
1424 class = enable_if_t<!__is_allocator<_Pred>::value>,
1425 class = enable_if_t<__is_allocator<_Allocator>::value>>
1349 class = enable_if_t<!__is_allocator_v<_Pred>>,
1350 class = enable_if_t<__is_allocator_v<_Allocator>>>
14261351unordered_map(initializer_list<pair<_Key, _Tp>>,
14271352 typename allocator_traits<_Allocator>::size_type = 0,
14281353 _Hash = _Hash(),
......@@ -1432,7 +1357,7 @@ unordered_map(initializer_list<pair<_Key, _Tp>>,
14321357template <class _InputIterator,
14331358 class _Allocator,
14341359 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1435 class = enable_if_t<__is_allocator<_Allocator>::value>>
1360 class = enable_if_t<__is_allocator_v<_Allocator>>>
14361361unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator)
14371362 -> unordered_map<__iter_key_type<_InputIterator>,
14381363 __iter_mapped_type<_InputIterator>,
......@@ -1443,7 +1368,7 @@ unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocat
14431368template <class _InputIterator,
14441369 class _Allocator,
14451370 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1446 class = enable_if_t<__is_allocator<_Allocator>::value>>
1371 class = enable_if_t<__is_allocator_v<_Allocator>>>
14471372unordered_map(_InputIterator, _InputIterator, _Allocator)
14481373 -> unordered_map<__iter_key_type<_InputIterator>,
14491374 __iter_mapped_type<_InputIterator>,
......@@ -1455,9 +1380,9 @@ template <class _InputIterator,
14551380 class _Hash,
14561381 class _Allocator,
14571382 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1458 class = enable_if_t<!__is_allocator<_Hash>::value>,
1383 class = enable_if_t<!__is_allocator_v<_Hash>>,
14591384 class = enable_if_t<!is_integral<_Hash>::value>,
1460 class = enable_if_t<__is_allocator<_Allocator>::value>>
1385 class = enable_if_t<__is_allocator_v<_Allocator>>>
14611386unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
14621387 -> unordered_map<__iter_key_type<_InputIterator>,
14631388 __iter_mapped_type<_InputIterator>,
......@@ -1467,7 +1392,7 @@ unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocat
14671392
14681393# if _LIBCPP_STD_VER >= 23
14691394
1470template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
1395template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
14711396unordered_map(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator)
14721397 -> unordered_map<__range_key_type<_Range>,
14731398 __range_mapped_type<_Range>,
......@@ -1475,7 +1400,7 @@ unordered_map(from_range_t, _Range&&, typename allocator_traits<_Allocator>::siz
14751400 equal_to<__range_key_type<_Range>>,
14761401 _Allocator>;
14771402
1478template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
1403template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
14791404unordered_map(from_range_t, _Range&&, _Allocator)
14801405 -> unordered_map<__range_key_type<_Range>,
14811406 __range_mapped_type<_Range>,
......@@ -1486,9 +1411,9 @@ unordered_map(from_range_t, _Range&&, _Allocator)
14861411template <ranges::input_range _Range,
14871412 class _Hash,
14881413 class _Allocator,
1489 class = enable_if_t<!__is_allocator<_Hash>::value>,
1414 class = enable_if_t<!__is_allocator_v<_Hash>>,
14901415 class = enable_if_t<!is_integral<_Hash>::value>,
1491 class = enable_if_t<__is_allocator<_Allocator>::value>>
1416 class = enable_if_t<__is_allocator_v<_Allocator>>>
14921417unordered_map(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
14931418 -> unordered_map<__range_key_type<_Range>,
14941419 __range_mapped_type<_Range>,
......@@ -1498,11 +1423,11 @@ unordered_map(from_range_t, _Range&&, typename allocator_traits<_Allocator>::siz
14981423
14991424# endif
15001425
1501template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
1426template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
15021427unordered_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Allocator)
15031428 -> unordered_map<remove_const_t<_Key>, _Tp, hash<remove_const_t<_Key>>, equal_to<remove_const_t<_Key>>, _Allocator>;
15041429
1505template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
1430template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
15061431unordered_map(initializer_list<pair<_Key, _Tp>>, _Allocator)
15071432 -> unordered_map<remove_const_t<_Key>, _Tp, hash<remove_const_t<_Key>>, equal_to<remove_const_t<_Key>>, _Allocator>;
15081433
......@@ -1510,9 +1435,9 @@ template <class _Key,
15101435 class _Tp,
15111436 class _Hash,
15121437 class _Allocator,
1513 class = enable_if_t<!__is_allocator<_Hash>::value>,
1438 class = enable_if_t<!__is_allocator_v<_Hash>>,
15141439 class = enable_if_t<!is_integral<_Hash>::value>,
1515 class = enable_if_t<__is_allocator<_Allocator>::value>>
1440 class = enable_if_t<__is_allocator_v<_Allocator>>>
15161441unordered_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
15171442 -> unordered_map<remove_const_t<_Key>, _Tp, _Hash, equal_to<remove_const_t<_Key>>, _Allocator>;
15181443# endif
......@@ -1563,12 +1488,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
15631488 insert(__first, __last);
15641489}
15651490
1566template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1567unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(const unordered_map& __u) : __table_(__u.__table_) {
1568 __table_.__rehash_unique(__u.bucket_count());
1569 insert(__u.begin(), __u.end());
1570}
1571
15721491template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
15731492unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(const unordered_map& __u, const allocator_type& __a)
15741493 : __table_(__u.__table_, typename __table::allocator_type(__a)) {
......@@ -1578,11 +1497,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(const unordered_ma
15781497
15791498# ifndef _LIBCPP_CXX03_LANG
15801499
1581template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1582inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(unordered_map&& __u)
1583 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
1584 : __table_(std::move(__u.__table_)) {}
1585
15861500template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
15871501unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(unordered_map&& __u, const allocator_type& __a)
15881502 : __table_(std::move(__u.__table_), typename __table::allocator_type(__a)) {
......@@ -1618,14 +1532,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
16181532 insert(__il.begin(), __il.end());
16191533}
16201534
1621template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1622inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&
1623unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_map&& __u)
1624 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) {
1625 __table_ = std::move(__u.__table_);
1626 return *this;
1627}
1628
16291535template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
16301536inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&
16311537unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(initializer_list<value_type> __il) {
......@@ -1646,16 +1552,13 @@ inline void unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterato
16461552
16471553template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
16481554_Tp& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) {
1649 return __table_
1650 .__emplace_unique_key_args(__k, piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple())
1555 return __table_.__emplace_unique(piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple())
16511556 .first->second;
16521557}
16531558
16541559template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
16551560_Tp& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](key_type&& __k) {
1656 return __table_
1657 .__emplace_unique_key_args(
1658 __k, piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple())
1561 return __table_.__emplace_unique(piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple())
16591562 .first->second;
16601563}
16611564# else // _LIBCPP_CXX03_LANG
......@@ -1781,12 +1684,8 @@ private:
17811684
17821685 __table __table_;
17831686
1784 typedef typename __table::_NodeTypes _NodeTypes;
17851687 typedef typename __table::__node_traits __node_traits;
1786 typedef typename __table::__node_allocator __node_allocator;
17871688 typedef typename __table::__node __node;
1788 typedef __hash_map_node_destructor<__node_allocator> _Dp;
1789 typedef unique_ptr<__node, _Dp> __node_holder;
17901689 typedef allocator_traits<allocator_type> __alloc_traits;
17911690 static_assert(is_same<typename __node_traits::size_type, typename __alloc_traits::size_type>::value,
17921691 "Allocator uses different size_type for different types");
......@@ -1852,11 +1751,10 @@ public:
18521751# endif
18531752
18541753 _LIBCPP_HIDE_FROM_ABI explicit unordered_multimap(const allocator_type& __a);
1855 _LIBCPP_HIDE_FROM_ABI unordered_multimap(const unordered_multimap& __u);
1754 _LIBCPP_HIDE_FROM_ABI unordered_multimap(const unordered_multimap& __u) = default;
18561755 _LIBCPP_HIDE_FROM_ABI unordered_multimap(const unordered_multimap& __u, const allocator_type& __a);
18571756# ifndef _LIBCPP_CXX03_LANG
1858 _LIBCPP_HIDE_FROM_ABI unordered_multimap(unordered_multimap&& __u)
1859 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
1757 _LIBCPP_HIDE_FROM_ABI unordered_multimap(unordered_multimap&& __u) = default;
18601758 _LIBCPP_HIDE_FROM_ABI unordered_multimap(unordered_multimap&& __u, const allocator_type& __a);
18611759 _LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list<value_type> __il);
18621760 _LIBCPP_HIDE_FROM_ABI unordered_multimap(
......@@ -1906,41 +1804,26 @@ public:
19061804 static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), "");
19071805 }
19081806
1909 _LIBCPP_HIDE_FROM_ABI unordered_multimap& operator=(const unordered_multimap& __u) {
1910# ifndef _LIBCPP_CXX03_LANG
1911 __table_ = __u.__table_;
1912# else
1913 if (this != std::addressof(__u)) {
1914 __table_.clear();
1915 __table_.hash_function() = __u.__table_.hash_function();
1916 __table_.key_eq() = __u.__table_.key_eq();
1917 __table_.max_load_factor() = __u.__table_.max_load_factor();
1918 __table_.__copy_assign_alloc(__u.__table_);
1919 insert(__u.begin(), __u.end());
1920 }
1921# endif
1922 return *this;
1923 }
1807 _LIBCPP_HIDE_FROM_ABI unordered_multimap& operator=(const unordered_multimap& __u) = default;
19241808# ifndef _LIBCPP_CXX03_LANG
1925 _LIBCPP_HIDE_FROM_ABI unordered_multimap& operator=(unordered_multimap&& __u)
1926 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
1809 _LIBCPP_HIDE_FROM_ABI unordered_multimap& operator=(unordered_multimap&& __u) = default;
19271810 _LIBCPP_HIDE_FROM_ABI unordered_multimap& operator=(initializer_list<value_type> __il);
19281811# endif // _LIBCPP_CXX03_LANG
19291812
1930 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
1813 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
19311814 return allocator_type(__table_.__node_alloc());
19321815 }
19331816
19341817 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __table_.size() == 0; }
1935 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __table_.size(); }
1936 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __table_.max_size(); }
1818 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __table_.size(); }
1819 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __table_.max_size(); }
19371820
1938 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __table_.begin(); }
1939 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __table_.end(); }
1940 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __table_.begin(); }
1941 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __table_.end(); }
1942 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __table_.begin(); }
1943 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __table_.end(); }
1821 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __table_.begin(); }
1822 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __table_.end(); }
1823 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __table_.begin(); }
1824 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __table_.end(); }
1825 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __table_.begin(); }
1826 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __table_.end(); }
19441827
19451828 _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __x) { return __table_.__emplace_multi(__x); }
19461829
......@@ -2008,10 +1891,10 @@ public:
20081891 "node_type with incompatible allocator passed to unordered_multimap::insert()");
20091892 return __table_.template __node_handle_insert_multi<node_type>(__hint.__i_, std::move(__nh));
20101893 }
2011 _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
1894 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
20121895 return __table_.template __node_handle_extract<node_type>(__key);
20131896 }
2014 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
1897 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
20151898 return __table_.template __node_handle_extract<node_type>(__it.__i_);
20161899 }
20171900
......@@ -2045,71 +1928,83 @@ public:
20451928 __table_.swap(__u.__table_);
20461929 }
20471930
2048 _LIBCPP_HIDE_FROM_ABI hasher hash_function() const { return __table_.hash_function().hash_function(); }
2049 _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq().key_eq(); }
1931 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI hasher hash_function() const {
1932 return __table_.hash_function().hash_function();
1933 }
1934 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq().key_eq(); }
20501935
2051 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
2052 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
1936 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
1937 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
20531938# if _LIBCPP_STD_VER >= 20
20541939 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
2055 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1940 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
20561941 return __table_.find(__k);
20571942 }
20581943 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
2059 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1944 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
20601945 return __table_.find(__k);
20611946 }
20621947# endif // _LIBCPP_STD_VER >= 20
20631948
2064 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_multi(__k); }
1949 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const {
1950 return __table_.__count_multi(__k);
1951 }
20651952# if _LIBCPP_STD_VER >= 20
20661953 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
2067 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1954 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
20681955 return __table_.__count_multi(__k);
20691956 }
20701957# endif // _LIBCPP_STD_VER >= 20
20711958
20721959# if _LIBCPP_STD_VER >= 20
2073 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1960 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
20741961
20751962 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
2076 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1963 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
20771964 return find(__k) != end();
20781965 }
20791966# endif // _LIBCPP_STD_VER >= 20
20801967
2081 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
1968 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
20821969 return __table_.__equal_range_multi(__k);
20831970 }
2084 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
1971 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
20851972 return __table_.__equal_range_multi(__k);
20861973 }
20871974# if _LIBCPP_STD_VER >= 20
20881975 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
2089 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
1976 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
20901977 return __table_.__equal_range_multi(__k);
20911978 }
20921979 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
2093 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
1980 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
20941981 return __table_.__equal_range_multi(__k);
20951982 }
20961983# endif // _LIBCPP_STD_VER >= 20
20971984
2098 _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __table_.bucket_count(); }
2099 _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT { return __table_.max_bucket_count(); }
1985 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __table_.bucket_count(); }
1986 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT {
1987 return __table_.max_bucket_count();
1988 }
21001989
2101 _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const { return __table_.bucket_size(__n); }
2102 _LIBCPP_HIDE_FROM_ABI size_type bucket(const key_type& __k) const { return __table_.bucket(__k); }
1990 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const {
1991 return __table_.bucket_size(__n);
1992 }
1993 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket(const key_type& __k) const { return __table_.bucket(__k); }
21031994
2104 _LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { return __table_.begin(__n); }
2105 _LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { return __table_.end(__n); }
2106 _LIBCPP_HIDE_FROM_ABI const_local_iterator begin(size_type __n) const { return __table_.cbegin(__n); }
2107 _LIBCPP_HIDE_FROM_ABI const_local_iterator end(size_type __n) const { return __table_.cend(__n); }
2108 _LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const { return __table_.cbegin(__n); }
2109 _LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { return __table_.cend(__n); }
1995 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { return __table_.begin(__n); }
1996 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { return __table_.end(__n); }
1997 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator begin(size_type __n) const {
1998 return __table_.cbegin(__n);
1999 }
2000 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator end(size_type __n) const { return __table_.cend(__n); }
2001 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const {
2002 return __table_.cbegin(__n);
2003 }
2004 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { return __table_.cend(__n); }
21102005
2111 _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { return __table_.load_factor(); }
2112 _LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __table_.max_load_factor(); }
2006 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { return __table_.load_factor(); }
2007 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __table_.max_load_factor(); }
21132008 _LIBCPP_HIDE_FROM_ABI void max_load_factor(float __mlf) { __table_.max_load_factor(__mlf); }
21142009 _LIBCPP_HIDE_FROM_ABI void rehash(size_type __n) { __table_.__rehash_multi(__n); }
21152010 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n) { __table_.__reserve_multi(__n); }
......@@ -2121,10 +2016,10 @@ template <class _InputIterator,
21212016 class _Pred = equal_to<__iter_key_type<_InputIterator>>,
21222017 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
21232018 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
2124 class = enable_if_t<!__is_allocator<_Hash>::value>,
2019 class = enable_if_t<!__is_allocator_v<_Hash>>,
21252020 class = enable_if_t<!is_integral<_Hash>::value>,
2126 class = enable_if_t<!__is_allocator<_Pred>::value>,
2127 class = enable_if_t<__is_allocator<_Allocator>::value>>
2021 class = enable_if_t<!__is_allocator_v<_Pred>>,
2022 class = enable_if_t<__is_allocator_v<_Allocator>>>
21282023unordered_multimap(_InputIterator,
21292024 _InputIterator,
21302025 typename allocator_traits<_Allocator>::size_type = 0,
......@@ -2142,10 +2037,10 @@ template <ranges::input_range _Range,
21422037 class _Hash = hash<__range_key_type<_Range>>,
21432038 class _Pred = equal_to<__range_key_type<_Range>>,
21442039 class _Allocator = allocator<__range_to_alloc_type<_Range>>,
2145 class = enable_if_t<!__is_allocator<_Hash>::value>,
2040 class = enable_if_t<!__is_allocator_v<_Hash>>,
21462041 class = enable_if_t<!is_integral<_Hash>::value>,
2147 class = enable_if_t<!__is_allocator<_Pred>::value>,
2148 class = enable_if_t<__is_allocator<_Allocator>::value>>
2042 class = enable_if_t<!__is_allocator_v<_Pred>>,
2043 class = enable_if_t<__is_allocator_v<_Allocator>>>
21492044unordered_multimap(from_range_t,
21502045 _Range&&,
21512046 typename allocator_traits<_Allocator>::size_type = 0,
......@@ -2160,21 +2055,21 @@ template <class _Key,
21602055 class _Hash = hash<remove_const_t<_Key>>,
21612056 class _Pred = equal_to<remove_const_t<_Key>>,
21622057 class _Allocator = allocator<pair<const _Key, _Tp>>,
2163 class = enable_if_t<!__is_allocator<_Hash>::value>,
2058 class = enable_if_t<!__is_allocator_v<_Hash>>,
21642059 class = enable_if_t<!is_integral<_Hash>::value>,
2165 class = enable_if_t<!__is_allocator<_Pred>::value>,
2166 class = enable_if_t<__is_allocator<_Allocator>::value>>
2167unordered_multimap(
2168 initializer_list<pair<_Key, _Tp>>,
2169 typename allocator_traits<_Allocator>::size_type = 0,
2170 _Hash = _Hash(),
2171 _Pred = _Pred(),
2172 _Allocator = _Allocator()) -> unordered_multimap<remove_const_t<_Key>, _Tp, _Hash, _Pred, _Allocator>;
2060 class = enable_if_t<!__is_allocator_v<_Pred>>,
2061 class = enable_if_t<__is_allocator_v<_Allocator>>>
2062unordered_multimap(initializer_list<pair<_Key, _Tp>>,
2063 typename allocator_traits<_Allocator>::size_type = 0,
2064 _Hash = _Hash(),
2065 _Pred = _Pred(),
2066 _Allocator = _Allocator())
2067 -> unordered_multimap<remove_const_t<_Key>, _Tp, _Hash, _Pred, _Allocator>;
21732068
21742069template <class _InputIterator,
21752070 class _Allocator,
21762071 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
2177 class = enable_if_t<__is_allocator<_Allocator>::value>>
2072 class = enable_if_t<__is_allocator_v<_Allocator>>>
21782073unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator)
21792074 -> unordered_multimap<__iter_key_type<_InputIterator>,
21802075 __iter_mapped_type<_InputIterator>,
......@@ -2185,7 +2080,7 @@ unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Al
21852080template <class _InputIterator,
21862081 class _Allocator,
21872082 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
2188 class = enable_if_t<__is_allocator<_Allocator>::value>>
2083 class = enable_if_t<__is_allocator_v<_Allocator>>>
21892084unordered_multimap(_InputIterator, _InputIterator, _Allocator)
21902085 -> unordered_multimap<__iter_key_type<_InputIterator>,
21912086 __iter_mapped_type<_InputIterator>,
......@@ -2197,9 +2092,9 @@ template <class _InputIterator,
21972092 class _Hash,
21982093 class _Allocator,
21992094 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
2200 class = enable_if_t<!__is_allocator<_Hash>::value>,
2095 class = enable_if_t<!__is_allocator_v<_Hash>>,
22012096 class = enable_if_t<!is_integral<_Hash>::value>,
2202 class = enable_if_t<__is_allocator<_Allocator>::value>>
2097 class = enable_if_t<__is_allocator_v<_Allocator>>>
22032098unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
22042099 -> unordered_multimap<__iter_key_type<_InputIterator>,
22052100 __iter_mapped_type<_InputIterator>,
......@@ -2209,7 +2104,7 @@ unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Al
22092104
22102105# if _LIBCPP_STD_VER >= 23
22112106
2212template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
2107template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
22132108unordered_multimap(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator)
22142109 -> unordered_multimap<__range_key_type<_Range>,
22152110 __range_mapped_type<_Range>,
......@@ -2217,7 +2112,7 @@ unordered_multimap(from_range_t, _Range&&, typename allocator_traits<_Allocator>
22172112 equal_to<__range_key_type<_Range>>,
22182113 _Allocator>;
22192114
2220template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
2115template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
22212116unordered_multimap(from_range_t, _Range&&, _Allocator)
22222117 -> unordered_multimap<__range_key_type<_Range>,
22232118 __range_mapped_type<_Range>,
......@@ -2228,9 +2123,9 @@ unordered_multimap(from_range_t, _Range&&, _Allocator)
22282123template <ranges::input_range _Range,
22292124 class _Hash,
22302125 class _Allocator,
2231 class = enable_if_t<!__is_allocator<_Hash>::value>,
2126 class = enable_if_t<!__is_allocator_v<_Hash>>,
22322127 class = enable_if_t<!is_integral<_Hash>::value>,
2233 class = enable_if_t<__is_allocator<_Allocator>::value>>
2128 class = enable_if_t<__is_allocator_v<_Allocator>>>
22342129unordered_multimap(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
22352130 -> unordered_multimap<__range_key_type<_Range>,
22362131 __range_mapped_type<_Range>,
......@@ -2240,7 +2135,7 @@ unordered_multimap(from_range_t, _Range&&, typename allocator_traits<_Allocator>
22402135
22412136# endif
22422137
2243template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
2138template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
22442139unordered_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Allocator)
22452140 -> unordered_multimap<remove_const_t<_Key>,
22462141 _Tp,
......@@ -2248,7 +2143,7 @@ unordered_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<
22482143 equal_to<remove_const_t<_Key>>,
22492144 _Allocator>;
22502145
2251template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
2146template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
22522147unordered_multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
22532148 -> unordered_multimap<remove_const_t<_Key>,
22542149 _Tp,
......@@ -2260,9 +2155,9 @@ template <class _Key,
22602155 class _Tp,
22612156 class _Hash,
22622157 class _Allocator,
2263 class = enable_if_t<!__is_allocator<_Hash>::value>,
2158 class = enable_if_t<!__is_allocator_v<_Hash>>,
22642159 class = enable_if_t<!is_integral<_Hash>::value>,
2265 class = enable_if_t<__is_allocator<_Allocator>::value>>
2160 class = enable_if_t<__is_allocator_v<_Allocator>>>
22662161unordered_multimap(
22672162 initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
22682163 -> unordered_multimap<remove_const_t<_Key>, _Tp, _Hash, equal_to<remove_const_t<_Key>>, _Allocator>;
......@@ -2315,13 +2210,6 @@ template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
23152210inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(const allocator_type& __a)
23162211 : __table_(typename __table::allocator_type(__a)) {}
23172212
2318template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2319unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(const unordered_multimap& __u)
2320 : __table_(__u.__table_) {
2321 __table_.__rehash_multi(__u.bucket_count());
2322 insert(__u.begin(), __u.end());
2323}
2324
23252213template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
23262214unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
23272215 const unordered_multimap& __u, const allocator_type& __a)
......@@ -2332,11 +2220,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
23322220
23332221# ifndef _LIBCPP_CXX03_LANG
23342222
2335template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2336inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(unordered_multimap&& __u)
2337 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
2338 : __table_(std::move(__u.__table_)) {}
2339
23402223template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
23412224unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
23422225 unordered_multimap&& __u, const allocator_type& __a)
......@@ -2373,14 +2256,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
23732256 insert(__il.begin(), __il.end());
23742257}
23752258
2376template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2377inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&
2378unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_multimap&& __u)
2379 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) {
2380 __table_ = std::move(__u.__table_);
2381 return *this;
2382}
2383
23842259template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
23852260inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&
23862261unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(initializer_list<value_type> __il) {
lib/libcxx/include/unordered_set+168-195
......@@ -544,8 +544,6 @@ template <class Value, class Hash, class Pred, class Alloc>
544544# include <__iterator/distance.h>
545545# include <__iterator/erase_if_container.h>
546546# include <__iterator/iterator_traits.h>
547# include <__iterator/ranges_iterator_traits.h>
548# include <__memory/addressof.h>
549547# include <__memory/allocator.h>
550548# include <__memory/allocator_traits.h>
551549# include <__memory_resource/polymorphic_allocator.h>
......@@ -558,7 +556,6 @@ template <class Value, class Hash, class Pred, class Alloc>
558556# include <__type_traits/invoke.h>
559557# include <__type_traits/is_allocator.h>
560558# include <__type_traits/is_integral.h>
561# include <__type_traits/is_nothrow_assignable.h>
562559# include <__type_traits/is_nothrow_constructible.h>
563560# include <__type_traits/is_same.h>
564561# include <__type_traits/is_swappable.h>
......@@ -703,10 +700,10 @@ public:
703700# endif
704701
705702 _LIBCPP_HIDE_FROM_ABI explicit unordered_set(const allocator_type& __a);
706 _LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u);
703 _LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u) = default;
707704 _LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u, const allocator_type& __a);
708705# ifndef _LIBCPP_CXX03_LANG
709 _LIBCPP_HIDE_FROM_ABI unordered_set(unordered_set&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
706 _LIBCPP_HIDE_FROM_ABI unordered_set(unordered_set&& __u) = default;
710707 _LIBCPP_HIDE_FROM_ABI unordered_set(unordered_set&& __u, const allocator_type& __a);
711708 _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il);
712709 _LIBCPP_HIDE_FROM_ABI
......@@ -733,30 +730,26 @@ public:
733730 static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), "");
734731 }
735732
736 _LIBCPP_HIDE_FROM_ABI unordered_set& operator=(const unordered_set& __u) {
737 __table_ = __u.__table_;
738 return *this;
739 }
733 _LIBCPP_HIDE_FROM_ABI unordered_set& operator=(const unordered_set& __u) = default;
740734# ifndef _LIBCPP_CXX03_LANG
741 _LIBCPP_HIDE_FROM_ABI unordered_set& operator=(unordered_set&& __u)
742 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
735 _LIBCPP_HIDE_FROM_ABI unordered_set& operator=(unordered_set&& __u) = default;
743736 _LIBCPP_HIDE_FROM_ABI unordered_set& operator=(initializer_list<value_type> __il);
744737# endif // _LIBCPP_CXX03_LANG
745738
746 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
739 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
747740 return allocator_type(__table_.__node_alloc());
748741 }
749742
750743 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __table_.size() == 0; }
751 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __table_.size(); }
752 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __table_.max_size(); }
744 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __table_.size(); }
745 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __table_.max_size(); }
753746
754 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __table_.begin(); }
755 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __table_.end(); }
756 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __table_.begin(); }
757 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __table_.end(); }
758 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __table_.begin(); }
759 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __table_.end(); }
747 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __table_.begin(); }
748 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __table_.end(); }
749 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __table_.begin(); }
750 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __table_.end(); }
751 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __table_.begin(); }
752 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __table_.end(); }
760753
761754# ifndef _LIBCPP_CXX03_LANG
762755 template <class... _Args>
......@@ -808,10 +801,10 @@ public:
808801 "node_type with incompatible allocator passed to unordered_set::insert()");
809802 return __table_.template __node_handle_insert_unique<node_type>(__h, std::move(__nh));
810803 }
811 _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
804 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
812805 return __table_.template __node_handle_extract<node_type>(__key);
813806 }
814 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
807 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
815808 return __table_.template __node_handle_extract<node_type>(__it);
816809 }
817810
......@@ -845,71 +838,81 @@ public:
845838 __table_.swap(__u.__table_);
846839 }
847840
848 _LIBCPP_HIDE_FROM_ABI hasher hash_function() const { return __table_.hash_function(); }
849 _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq(); }
841 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI hasher hash_function() const { return __table_.hash_function(); }
842 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq(); }
850843
851 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
852 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
844 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
845 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
853846# if _LIBCPP_STD_VER >= 20
854847 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
855 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
848 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
856849 return __table_.find(__k);
857850 }
858851 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
859 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
852 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
860853 return __table_.find(__k);
861854 }
862855# endif // _LIBCPP_STD_VER >= 20
863856
864 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_unique(__k); }
857 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const {
858 return __table_.__count_unique(__k);
859 }
865860# if _LIBCPP_STD_VER >= 20
866861 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
867 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
862 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
868863 return __table_.__count_unique(__k);
869864 }
870865# endif // _LIBCPP_STD_VER >= 20
871866
872867# if _LIBCPP_STD_VER >= 20
873 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
868 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
874869
875870 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
876 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
871 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
877872 return find(__k) != end();
878873 }
879874# endif // _LIBCPP_STD_VER >= 20
880875
881 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
876 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
882877 return __table_.__equal_range_unique(__k);
883878 }
884 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
879 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
885880 return __table_.__equal_range_unique(__k);
886881 }
887882# if _LIBCPP_STD_VER >= 20
888883 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
889 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
884 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
890885 return __table_.__equal_range_unique(__k);
891886 }
892887 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
893 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
888 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
894889 return __table_.__equal_range_unique(__k);
895890 }
896891# endif // _LIBCPP_STD_VER >= 20
897892
898 _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __table_.bucket_count(); }
899 _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT { return __table_.max_bucket_count(); }
893 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __table_.bucket_count(); }
894 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT {
895 return __table_.max_bucket_count();
896 }
900897
901 _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const { return __table_.bucket_size(__n); }
902 _LIBCPP_HIDE_FROM_ABI size_type bucket(const key_type& __k) const { return __table_.bucket(__k); }
898 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const {
899 return __table_.bucket_size(__n);
900 }
901 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket(const key_type& __k) const { return __table_.bucket(__k); }
903902
904 _LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { return __table_.begin(__n); }
905 _LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { return __table_.end(__n); }
906 _LIBCPP_HIDE_FROM_ABI const_local_iterator begin(size_type __n) const { return __table_.cbegin(__n); }
907 _LIBCPP_HIDE_FROM_ABI const_local_iterator end(size_type __n) const { return __table_.cend(__n); }
908 _LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const { return __table_.cbegin(__n); }
909 _LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { return __table_.cend(__n); }
903 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { return __table_.begin(__n); }
904 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { return __table_.end(__n); }
905 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator begin(size_type __n) const {
906 return __table_.cbegin(__n);
907 }
908 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator end(size_type __n) const { return __table_.cend(__n); }
909 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const {
910 return __table_.cbegin(__n);
911 }
912 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { return __table_.cend(__n); }
910913
911 _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { return __table_.load_factor(); }
912 _LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __table_.max_load_factor(); }
914 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { return __table_.load_factor(); }
915 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __table_.max_load_factor(); }
913916 _LIBCPP_HIDE_FROM_ABI void max_load_factor(float __mlf) { __table_.max_load_factor(__mlf); }
914917 _LIBCPP_HIDE_FROM_ABI void rehash(size_type __n) { __table_.__rehash_unique(__n); }
915918 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n) { __table_.__reserve_unique(__n); }
......@@ -917,47 +920,48 @@ public:
917920
918921# if _LIBCPP_STD_VER >= 17
919922template <class _InputIterator,
920 class _Hash = hash<__iter_value_type<_InputIterator>>,
921 class _Pred = equal_to<__iter_value_type<_InputIterator>>,
922 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
923 class _Hash = hash<__iterator_value_type<_InputIterator>>,
924 class _Pred = equal_to<__iterator_value_type<_InputIterator>>,
925 class _Allocator = allocator<__iterator_value_type<_InputIterator>>,
923926 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
924 class = enable_if_t<!__is_allocator<_Hash>::value>,
927 class = enable_if_t<!__is_allocator_v<_Hash>>,
925928 class = enable_if_t<!is_integral<_Hash>::value>,
926 class = enable_if_t<!__is_allocator<_Pred>::value>,
927 class = enable_if_t<__is_allocator<_Allocator>::value>>
929 class = enable_if_t<!__is_allocator_v<_Pred>>,
930 class = enable_if_t<__is_allocator_v<_Allocator>>>
928931unordered_set(_InputIterator,
929932 _InputIterator,
930933 typename allocator_traits<_Allocator>::size_type = 0,
931934 _Hash = _Hash(),
932935 _Pred = _Pred(),
933 _Allocator = _Allocator()) -> unordered_set<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>;
936 _Allocator = _Allocator())
937 -> unordered_set<__iterator_value_type<_InputIterator>, _Hash, _Pred, _Allocator>;
934938
935939# if _LIBCPP_STD_VER >= 23
936940template <ranges::input_range _Range,
937941 class _Hash = hash<ranges::range_value_t<_Range>>,
938942 class _Pred = equal_to<ranges::range_value_t<_Range>>,
939943 class _Allocator = allocator<ranges::range_value_t<_Range>>,
940 class = enable_if_t<!__is_allocator<_Hash>::value>,
944 class = enable_if_t<!__is_allocator_v<_Hash>>,
941945 class = enable_if_t<!is_integral<_Hash>::value>,
942 class = enable_if_t<!__is_allocator<_Pred>::value>,
943 class = enable_if_t<__is_allocator<_Allocator>::value>>
944unordered_set(
945 from_range_t,
946 _Range&&,
947 typename allocator_traits<_Allocator>::size_type = 0,
948 _Hash = _Hash(),
949 _Pred = _Pred(),
950 _Allocator = _Allocator()) -> unordered_set<ranges::range_value_t<_Range>, _Hash, _Pred, _Allocator>; // C++23
946 class = enable_if_t<!__is_allocator_v<_Pred>>,
947 class = enable_if_t<__is_allocator_v<_Allocator>>>
948unordered_set(from_range_t,
949 _Range&&,
950 typename allocator_traits<_Allocator>::size_type = 0,
951 _Hash = _Hash(),
952 _Pred = _Pred(),
953 _Allocator = _Allocator())
954 -> unordered_set<ranges::range_value_t<_Range>, _Hash, _Pred, _Allocator>; // C++23
951955# endif
952956
953957template <class _Tp,
954958 class _Hash = hash<_Tp>,
955959 class _Pred = equal_to<_Tp>,
956960 class _Allocator = allocator<_Tp>,
957 class = enable_if_t<!__is_allocator<_Hash>::value>,
961 class = enable_if_t<!__is_allocator_v<_Hash>>,
958962 class = enable_if_t<!is_integral<_Hash>::value>,
959 class = enable_if_t<!__is_allocator<_Pred>::value>,
960 class = enable_if_t<__is_allocator<_Allocator>::value>>
963 class = enable_if_t<!__is_allocator_v<_Pred>>,
964 class = enable_if_t<__is_allocator_v<_Allocator>>>
961965unordered_set(initializer_list<_Tp>,
962966 typename allocator_traits<_Allocator>::size_type = 0,
963967 _Hash = _Hash(),
......@@ -967,33 +971,36 @@ unordered_set(initializer_list<_Tp>,
967971template <class _InputIterator,
968972 class _Allocator,
969973 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
970 class = enable_if_t<__is_allocator<_Allocator>::value>>
974 class = enable_if_t<__is_allocator_v<_Allocator>>>
971975unordered_set(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator)
972 -> unordered_set<__iter_value_type<_InputIterator>,
973 hash<__iter_value_type<_InputIterator>>,
974 equal_to<__iter_value_type<_InputIterator>>,
976 -> unordered_set<__iterator_value_type<_InputIterator>,
977 hash<__iterator_value_type<_InputIterator>>,
978 equal_to<__iterator_value_type<_InputIterator>>,
975979 _Allocator>;
976980
977981template <class _InputIterator,
978982 class _Hash,
979983 class _Allocator,
980984 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
981 class = enable_if_t<!__is_allocator<_Hash>::value>,
985 class = enable_if_t<!__is_allocator_v<_Hash>>,
982986 class = enable_if_t<!is_integral<_Hash>::value>,
983 class = enable_if_t<__is_allocator<_Allocator>::value>>
987 class = enable_if_t<__is_allocator_v<_Allocator>>>
984988unordered_set(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
985 -> unordered_set<__iter_value_type<_InputIterator>, _Hash, equal_to<__iter_value_type<_InputIterator>>, _Allocator>;
989 -> unordered_set<__iterator_value_type<_InputIterator>,
990 _Hash,
991 equal_to<__iterator_value_type<_InputIterator>>,
992 _Allocator>;
986993
987994# if _LIBCPP_STD_VER >= 23
988995
989template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
996template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
990997unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator)
991998 -> unordered_set<ranges::range_value_t<_Range>,
992999 hash<ranges::range_value_t<_Range>>,
9931000 equal_to<ranges::range_value_t<_Range>>,
9941001 _Allocator>;
9951002
996template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
1003template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
9971004unordered_set(from_range_t, _Range&&, _Allocator)
9981005 -> unordered_set<ranges::range_value_t<_Range>,
9991006 hash<ranges::range_value_t<_Range>>,
......@@ -1003,24 +1010,24 @@ unordered_set(from_range_t, _Range&&, _Allocator)
10031010template <ranges::input_range _Range,
10041011 class _Hash,
10051012 class _Allocator,
1006 class = enable_if_t<!__is_allocator<_Hash>::value>,
1013 class = enable_if_t<!__is_allocator_v<_Hash>>,
10071014 class = enable_if_t<!is_integral<_Hash>::value>,
1008 class = enable_if_t<__is_allocator<_Allocator>::value>>
1015 class = enable_if_t<__is_allocator_v<_Allocator>>>
10091016unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
10101017 -> unordered_set<ranges::range_value_t<_Range>, _Hash, equal_to<ranges::range_value_t<_Range>>, _Allocator>;
10111018
10121019# endif
10131020
1014template <class _Tp, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
1021template <class _Tp, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
10151022unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator)
10161023 -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
10171024
10181025template <class _Tp,
10191026 class _Hash,
10201027 class _Allocator,
1021 class = enable_if_t<!__is_allocator<_Hash>::value>,
1028 class = enable_if_t<!__is_allocator_v<_Hash>>,
10221029 class = enable_if_t<!is_integral<_Hash>::value>,
1023 class = enable_if_t<__is_allocator<_Allocator>::value>>
1030 class = enable_if_t<__is_allocator_v<_Allocator>>>
10241031unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
10251032 -> unordered_set<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
10261033# endif
......@@ -1070,12 +1077,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
10701077template <class _Value, class _Hash, class _Pred, class _Alloc>
10711078inline unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(const allocator_type& __a) : __table_(__a) {}
10721079
1073template <class _Value, class _Hash, class _Pred, class _Alloc>
1074unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(const unordered_set& __u) : __table_(__u.__table_) {
1075 __table_.__rehash_unique(__u.bucket_count());
1076 insert(__u.begin(), __u.end());
1077}
1078
10791080template <class _Value, class _Hash, class _Pred, class _Alloc>
10801081unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(const unordered_set& __u, const allocator_type& __a)
10811082 : __table_(__u.__table_, __a) {
......@@ -1085,11 +1086,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(const unordered_set&
10851086
10861087# ifndef _LIBCPP_CXX03_LANG
10871088
1088template <class _Value, class _Hash, class _Pred, class _Alloc>
1089inline unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(unordered_set&& __u)
1090 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
1091 : __table_(std::move(__u.__table_)) {}
1092
10931089template <class _Value, class _Hash, class _Pred, class _Alloc>
10941090unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(unordered_set&& __u, const allocator_type& __a)
10951091 : __table_(std::move(__u.__table_), __a) {
......@@ -1125,14 +1121,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
11251121 insert(__il.begin(), __il.end());
11261122}
11271123
1128template <class _Value, class _Hash, class _Pred, class _Alloc>
1129inline unordered_set<_Value, _Hash, _Pred, _Alloc>&
1130unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(unordered_set&& __u)
1131 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) {
1132 __table_ = std::move(__u.__table_);
1133 return *this;
1134}
1135
11361124template <class _Value, class _Hash, class _Pred, class _Alloc>
11371125inline unordered_set<_Value, _Hash, _Pred, _Alloc>&
11381126unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(initializer_list<value_type> __il) {
......@@ -1308,11 +1296,10 @@ public:
13081296# endif
13091297
13101298 _LIBCPP_HIDE_FROM_ABI explicit unordered_multiset(const allocator_type& __a);
1311 _LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u);
1299 _LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u) = default;
13121300 _LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u, const allocator_type& __a);
13131301# ifndef _LIBCPP_CXX03_LANG
1314 _LIBCPP_HIDE_FROM_ABI unordered_multiset(unordered_multiset&& __u)
1315 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
1302 _LIBCPP_HIDE_FROM_ABI unordered_multiset(unordered_multiset&& __u) = default;
13161303 _LIBCPP_HIDE_FROM_ABI unordered_multiset(unordered_multiset&& __u, const allocator_type& __a);
13171304 _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il);
13181305 _LIBCPP_HIDE_FROM_ABI unordered_multiset(
......@@ -1339,30 +1326,26 @@ public:
13391326 static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), "");
13401327 }
13411328
1342 _LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(const unordered_multiset& __u) {
1343 __table_ = __u.__table_;
1344 return *this;
1345 }
1329 _LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(const unordered_multiset& __u) = default;
13461330# ifndef _LIBCPP_CXX03_LANG
1347 _LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(unordered_multiset&& __u)
1348 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
1331 _LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(unordered_multiset&& __u) = default;
13491332 _LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(initializer_list<value_type> __il);
13501333# endif // _LIBCPP_CXX03_LANG
13511334
1352 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
1335 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
13531336 return allocator_type(__table_.__node_alloc());
13541337 }
13551338
13561339 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __table_.size() == 0; }
1357 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __table_.size(); }
1358 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __table_.max_size(); }
1340 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __table_.size(); }
1341 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __table_.max_size(); }
13591342
1360 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __table_.begin(); }
1361 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __table_.end(); }
1362 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __table_.begin(); }
1363 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __table_.end(); }
1364 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __table_.begin(); }
1365 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __table_.end(); }
1343 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __table_.begin(); }
1344 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __table_.end(); }
1345 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __table_.begin(); }
1346 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __table_.end(); }
1347 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __table_.begin(); }
1348 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __table_.end(); }
13661349
13671350# ifndef _LIBCPP_CXX03_LANG
13681351 template <class... _Args>
......@@ -1410,10 +1393,10 @@ public:
14101393 "node_type with incompatible allocator passed to unordered_multiset::insert()");
14111394 return __table_.template __node_handle_insert_multi<node_type>(__hint, std::move(__nh));
14121395 }
1413 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __position) {
1396 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __position) {
14141397 return __table_.template __node_handle_extract<node_type>(__position);
14151398 }
1416 _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
1399 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
14171400 return __table_.template __node_handle_extract<node_type>(__key);
14181401 }
14191402
......@@ -1454,71 +1437,81 @@ public:
14541437 __table_.swap(__u.__table_);
14551438 }
14561439
1457 _LIBCPP_HIDE_FROM_ABI hasher hash_function() const { return __table_.hash_function(); }
1458 _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq(); }
1440 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI hasher hash_function() const { return __table_.hash_function(); }
1441 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq(); }
14591442
1460 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
1461 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
1443 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
1444 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
14621445# if _LIBCPP_STD_VER >= 20
14631446 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1464 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1447 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
14651448 return __table_.find(__k);
14661449 }
14671450 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1468 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1451 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
14691452 return __table_.find(__k);
14701453 }
14711454# endif // _LIBCPP_STD_VER >= 20
14721455
1473 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_multi(__k); }
1456 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const {
1457 return __table_.__count_multi(__k);
1458 }
14741459# if _LIBCPP_STD_VER >= 20
14751460 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1476 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1461 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
14771462 return __table_.__count_multi(__k);
14781463 }
14791464# endif // _LIBCPP_STD_VER >= 20
14801465
14811466# if _LIBCPP_STD_VER >= 20
1482 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1467 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
14831468
14841469 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1485 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1470 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
14861471 return find(__k) != end();
14871472 }
14881473# endif // _LIBCPP_STD_VER >= 20
14891474
1490 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
1475 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
14911476 return __table_.__equal_range_multi(__k);
14921477 }
1493 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
1478 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
14941479 return __table_.__equal_range_multi(__k);
14951480 }
14961481# if _LIBCPP_STD_VER >= 20
14971482 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1498 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
1483 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
14991484 return __table_.__equal_range_multi(__k);
15001485 }
15011486 template <class _K2, enable_if_t<__is_transparent_v<hasher, _K2> && __is_transparent_v<key_equal, _K2>>* = nullptr>
1502 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
1487 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
15031488 return __table_.__equal_range_multi(__k);
15041489 }
15051490# endif // _LIBCPP_STD_VER >= 20
15061491
1507 _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __table_.bucket_count(); }
1508 _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT { return __table_.max_bucket_count(); }
1492 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __table_.bucket_count(); }
1493 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT {
1494 return __table_.max_bucket_count();
1495 }
15091496
1510 _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const { return __table_.bucket_size(__n); }
1511 _LIBCPP_HIDE_FROM_ABI size_type bucket(const key_type& __k) const { return __table_.bucket(__k); }
1497 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const {
1498 return __table_.bucket_size(__n);
1499 }
1500 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type bucket(const key_type& __k) const { return __table_.bucket(__k); }
15121501
1513 _LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { return __table_.begin(__n); }
1514 _LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { return __table_.end(__n); }
1515 _LIBCPP_HIDE_FROM_ABI const_local_iterator begin(size_type __n) const { return __table_.cbegin(__n); }
1516 _LIBCPP_HIDE_FROM_ABI const_local_iterator end(size_type __n) const { return __table_.cend(__n); }
1517 _LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const { return __table_.cbegin(__n); }
1518 _LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { return __table_.cend(__n); }
1502 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { return __table_.begin(__n); }
1503 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { return __table_.end(__n); }
1504 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator begin(size_type __n) const {
1505 return __table_.cbegin(__n);
1506 }
1507 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator end(size_type __n) const { return __table_.cend(__n); }
1508 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const {
1509 return __table_.cbegin(__n);
1510 }
1511 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { return __table_.cend(__n); }
15191512
1520 _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { return __table_.load_factor(); }
1521 _LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __table_.max_load_factor(); }
1513 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { return __table_.load_factor(); }
1514 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __table_.max_load_factor(); }
15221515 _LIBCPP_HIDE_FROM_ABI void max_load_factor(float __mlf) { __table_.max_load_factor(__mlf); }
15231516 _LIBCPP_HIDE_FROM_ABI void rehash(size_type __n) { __table_.__rehash_multi(__n); }
15241517 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n) { __table_.__reserve_multi(__n); }
......@@ -1526,31 +1519,31 @@ public:
15261519
15271520# if _LIBCPP_STD_VER >= 17
15281521template <class _InputIterator,
1529 class _Hash = hash<__iter_value_type<_InputIterator>>,
1530 class _Pred = equal_to<__iter_value_type<_InputIterator>>,
1531 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
1522 class _Hash = hash<__iterator_value_type<_InputIterator>>,
1523 class _Pred = equal_to<__iterator_value_type<_InputIterator>>,
1524 class _Allocator = allocator<__iterator_value_type<_InputIterator>>,
15321525 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1533 class = enable_if_t<!__is_allocator<_Hash>::value>,
1526 class = enable_if_t<!__is_allocator_v<_Hash>>,
15341527 class = enable_if_t<!is_integral<_Hash>::value>,
1535 class = enable_if_t<!__is_allocator<_Pred>::value>,
1536 class = enable_if_t<__is_allocator<_Allocator>::value>>
1528 class = enable_if_t<!__is_allocator_v<_Pred>>,
1529 class = enable_if_t<__is_allocator_v<_Allocator>>>
15371530unordered_multiset(
15381531 _InputIterator,
15391532 _InputIterator,
15401533 typename allocator_traits<_Allocator>::size_type = 0,
15411534 _Hash = _Hash(),
15421535 _Pred = _Pred(),
1543 _Allocator = _Allocator()) -> unordered_multiset<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>;
1536 _Allocator = _Allocator()) -> unordered_multiset<__iterator_value_type<_InputIterator>, _Hash, _Pred, _Allocator>;
15441537
15451538# if _LIBCPP_STD_VER >= 23
15461539template <ranges::input_range _Range,
15471540 class _Hash = hash<ranges::range_value_t<_Range>>,
15481541 class _Pred = equal_to<ranges::range_value_t<_Range>>,
15491542 class _Allocator = allocator<ranges::range_value_t<_Range>>,
1550 class = enable_if_t<!__is_allocator<_Hash>::value>,
1543 class = enable_if_t<!__is_allocator_v<_Hash>>,
15511544 class = enable_if_t<!is_integral<_Hash>::value>,
1552 class = enable_if_t<!__is_allocator<_Pred>::value>,
1553 class = enable_if_t<__is_allocator<_Allocator>::value>>
1545 class = enable_if_t<!__is_allocator_v<_Pred>>,
1546 class = enable_if_t<__is_allocator_v<_Allocator>>>
15541547unordered_multiset(
15551548 from_range_t,
15561549 _Range&&,
......@@ -1564,10 +1557,10 @@ template <class _Tp,
15641557 class _Hash = hash<_Tp>,
15651558 class _Pred = equal_to<_Tp>,
15661559 class _Allocator = allocator<_Tp>,
1567 class = enable_if_t<!__is_allocator<_Hash>::value>,
1560 class = enable_if_t<!__is_allocator_v<_Hash>>,
15681561 class = enable_if_t<!is_integral<_Hash>::value>,
1569 class = enable_if_t<!__is_allocator<_Pred>::value>,
1570 class = enable_if_t<__is_allocator<_Allocator>::value>>
1562 class = enable_if_t<!__is_allocator_v<_Pred>>,
1563 class = enable_if_t<__is_allocator_v<_Allocator>>>
15711564unordered_multiset(initializer_list<_Tp>,
15721565 typename allocator_traits<_Allocator>::size_type = 0,
15731566 _Hash = _Hash(),
......@@ -1577,36 +1570,36 @@ unordered_multiset(initializer_list<_Tp>,
15771570template <class _InputIterator,
15781571 class _Allocator,
15791572 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1580 class = enable_if_t<__is_allocator<_Allocator>::value>>
1573 class = enable_if_t<__is_allocator_v<_Allocator>>>
15811574unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator)
1582 -> unordered_multiset<__iter_value_type<_InputIterator>,
1583 hash<__iter_value_type<_InputIterator>>,
1584 equal_to<__iter_value_type<_InputIterator>>,
1575 -> unordered_multiset<__iterator_value_type<_InputIterator>,
1576 hash<__iterator_value_type<_InputIterator>>,
1577 equal_to<__iterator_value_type<_InputIterator>>,
15851578 _Allocator>;
15861579
15871580template <class _InputIterator,
15881581 class _Hash,
15891582 class _Allocator,
15901583 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
1591 class = enable_if_t<!__is_allocator<_Hash>::value>,
1584 class = enable_if_t<!__is_allocator_v<_Hash>>,
15921585 class = enable_if_t<!is_integral<_Hash>::value>,
1593 class = enable_if_t<__is_allocator<_Allocator>::value>>
1586 class = enable_if_t<__is_allocator_v<_Allocator>>>
15941587unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
1595 -> unordered_multiset<__iter_value_type<_InputIterator>,
1588 -> unordered_multiset<__iterator_value_type<_InputIterator>,
15961589 _Hash,
1597 equal_to<__iter_value_type<_InputIterator>>,
1590 equal_to<__iterator_value_type<_InputIterator>>,
15981591 _Allocator>;
15991592
16001593# if _LIBCPP_STD_VER >= 23
16011594
1602template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
1595template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
16031596unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator)
16041597 -> unordered_multiset<ranges::range_value_t<_Range>,
16051598 hash<ranges::range_value_t<_Range>>,
16061599 equal_to<ranges::range_value_t<_Range>>,
16071600 _Allocator>;
16081601
1609template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
1602template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
16101603unordered_multiset(from_range_t, _Range&&, _Allocator)
16111604 -> unordered_multiset<ranges::range_value_t<_Range>,
16121605 hash<ranges::range_value_t<_Range>>,
......@@ -1616,24 +1609,24 @@ unordered_multiset(from_range_t, _Range&&, _Allocator)
16161609template <ranges::input_range _Range,
16171610 class _Hash,
16181611 class _Allocator,
1619 class = enable_if_t<!__is_allocator<_Hash>::value>,
1612 class = enable_if_t<!__is_allocator_v<_Hash>>,
16201613 class = enable_if_t<!is_integral<_Hash>::value>,
1621 class = enable_if_t<__is_allocator<_Allocator>::value>>
1614 class = enable_if_t<__is_allocator_v<_Allocator>>>
16221615unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
16231616 -> unordered_multiset<ranges::range_value_t<_Range>, _Hash, equal_to<ranges::range_value_t<_Range>>, _Allocator>;
16241617
16251618# endif
16261619
1627template <class _Tp, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>>
1620template <class _Tp, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>
16281621unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator)
16291622 -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
16301623
16311624template <class _Tp,
16321625 class _Hash,
16331626 class _Allocator,
1634 class = enable_if_t<!__is_allocator<_Hash>::value>,
1627 class = enable_if_t<!__is_allocator_v<_Hash>>,
16351628 class = enable_if_t<!is_integral<_Hash>::value>,
1636 class = enable_if_t<__is_allocator<_Allocator>::value>>
1629 class = enable_if_t<__is_allocator_v<_Allocator>>>
16371630unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
16381631 -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
16391632# endif
......@@ -1685,13 +1678,6 @@ template <class _Value, class _Hash, class _Pred, class _Alloc>
16851678inline unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(const allocator_type& __a)
16861679 : __table_(__a) {}
16871680
1688template <class _Value, class _Hash, class _Pred, class _Alloc>
1689unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(const unordered_multiset& __u)
1690 : __table_(__u.__table_) {
1691 __table_.__rehash_multi(__u.bucket_count());
1692 insert(__u.begin(), __u.end());
1693}
1694
16951681template <class _Value, class _Hash, class _Pred, class _Alloc>
16961682unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
16971683 const unordered_multiset& __u, const allocator_type& __a)
......@@ -1702,11 +1688,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
17021688
17031689# ifndef _LIBCPP_CXX03_LANG
17041690
1705template <class _Value, class _Hash, class _Pred, class _Alloc>
1706inline unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(unordered_multiset&& __u)
1707 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
1708 : __table_(std::move(__u.__table_)) {}
1709
17101691template <class _Value, class _Hash, class _Pred, class _Alloc>
17111692unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
17121693 unordered_multiset&& __u, const allocator_type& __a)
......@@ -1743,14 +1724,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
17431724 insert(__il.begin(), __il.end());
17441725}
17451726
1746template <class _Value, class _Hash, class _Pred, class _Alloc>
1747inline unordered_multiset<_Value, _Hash, _Pred, _Alloc>&
1748unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=(unordered_multiset&& __u)
1749 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) {
1750 __table_ = std::move(__u.__table_);
1751 return *this;
1752}
1753
17541727template <class _Value, class _Hash, class _Pred, class _Alloc>
17551728inline unordered_multiset<_Value, _Hash, _Pred, _Alloc>&
17561729unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=(initializer_list<value_type> __il) {
lib/libcxx/include/utility+12
......@@ -216,6 +216,18 @@ template<size_t N>
216216template<class... T>
217217 using index_sequence_for = make_index_sequence<sizeof...(T)>;
218218
219template<class T, T... Values> // C++26
220 struct tuple_size<integer_sequence<T, Values...>>;
221
222template<size_t I, class T, T... Values> // C++26
223 struct tuple_element<I, integer_sequence<T, Values...>>;
224
225template<size_t I, class T, T... Values> // C++26
226 struct tuple_element<I, const integer_sequence<T, Values...>>;
227
228template<size_t I, class T, T... Values> // C++26
229 constexpr T get(integer_sequence<T, Values...>) noexcept;
230
219231template<class T, class U=T>
220232 constexpr T exchange(T& obj, U&& new_value) // constexpr in C++17, noexcept in C++23
221233 noexcept(is_nothrow_move_constructible<T>::value && is_nothrow_assignable<T&, U>::value);
lib/libcxx/include/valarray+106-161
......@@ -362,6 +362,7 @@ template <class T> unspecified2 end(const valarray<T>& v);
362362# include <__memory/uninitialized_algorithms.h>
363363# include <__type_traits/decay.h>
364364# include <__type_traits/remove_reference.h>
365# include <__utility/exception_guard.h>
365366# include <__utility/move.h>
366367# include <__utility/swap.h>
367368# include <cmath>
......@@ -395,9 +396,9 @@ public:
395396 _LIBCPP_HIDE_FROM_ABI slice(size_t __start, size_t __size, size_t __stride)
396397 : __start_(__start), __size_(__size), __stride_(__stride) {}
397398
398 _LIBCPP_HIDE_FROM_ABI size_t start() const { return __start_; }
399 _LIBCPP_HIDE_FROM_ABI size_t size() const { return __size_; }
400 _LIBCPP_HIDE_FROM_ABI size_t stride() const { return __stride_; }
399 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t start() const { return __start_; }
400 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t size() const { return __size_; }
401 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t stride() const { return __stride_; }
401402
402403# if _LIBCPP_STD_VER >= 20
403404
......@@ -792,7 +793,7 @@ private:
792793public:
793794 // construct/destroy:
794795 _LIBCPP_HIDE_FROM_ABI valarray() : __begin_(nullptr), __end_(nullptr) {}
795 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit valarray(size_t __n);
796 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 explicit valarray(size_t __n);
796797 _LIBCPP_HIDE_FROM_ABI valarray(const value_type& __x, size_t __n);
797798 valarray(const value_type* __p, size_t __n);
798799 valarray(const valarray& __v);
......@@ -804,7 +805,7 @@ public:
804805 valarray(const gslice_array<value_type>& __ga);
805806 valarray(const mask_array<value_type>& __ma);
806807 valarray(const indirect_array<value_type>& __ia);
807 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 ~valarray();
808 inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 ~valarray();
808809
809810 // assignment:
810811 valarray& operator=(const valarray& __v);
......@@ -821,36 +822,41 @@ public:
821822 _LIBCPP_HIDE_FROM_ABI valarray& operator=(const __val_expr<_ValExpr>& __v);
822823
823824 // element access:
824 _LIBCPP_HIDE_FROM_ABI const value_type& operator[](size_t __i) const {
825 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const value_type& operator[](size_t __i) const {
825826 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "valarray::operator[] index out of bounds");
826827 return __begin_[__i];
827828 }
828829
829 _LIBCPP_HIDE_FROM_ABI value_type& operator[](size_t __i) {
830 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_type& operator[](size_t __i) {
830831 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "valarray::operator[] index out of bounds");
831832 return __begin_[__i];
832833 }
833834
834835 // subset operations:
835 _LIBCPP_HIDE_FROM_ABI __val_expr<__slice_expr<const valarray&> > operator[](slice __s) const;
836 _LIBCPP_HIDE_FROM_ABI slice_array<value_type> operator[](slice __s);
837 _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr<const valarray&> > operator[](const gslice& __gs) const;
838 _LIBCPP_HIDE_FROM_ABI gslice_array<value_type> operator[](const gslice& __gs);
836 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __val_expr<__slice_expr<const valarray&> > operator[](slice __s) const;
837 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI slice_array<value_type> operator[](slice __s);
838 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr<const valarray&> >
839 operator[](const gslice& __gs) const;
840 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI gslice_array<value_type> operator[](const gslice& __gs);
839841# ifndef _LIBCPP_CXX03_LANG
840 _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr<const valarray&> > operator[](gslice&& __gs) const;
841 _LIBCPP_HIDE_FROM_ABI gslice_array<value_type> operator[](gslice&& __gs);
842 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr<const valarray&> > operator[](gslice&& __gs) const;
843 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI gslice_array<value_type> operator[](gslice&& __gs);
842844# endif // _LIBCPP_CXX03_LANG
845 [[__nodiscard__]]
843846 _LIBCPP_HIDE_FROM_ABI __val_expr<__mask_expr<const valarray&> > operator[](const valarray<bool>& __vb) const;
844 _LIBCPP_HIDE_FROM_ABI mask_array<value_type> operator[](const valarray<bool>& __vb);
847 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mask_array<value_type> operator[](const valarray<bool>& __vb);
845848# ifndef _LIBCPP_CXX03_LANG
849 [[__nodiscard__]]
846850 _LIBCPP_HIDE_FROM_ABI __val_expr<__mask_expr<const valarray&> > operator[](valarray<bool>&& __vb) const;
847 _LIBCPP_HIDE_FROM_ABI mask_array<value_type> operator[](valarray<bool>&& __vb);
851 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mask_array<value_type> operator[](valarray<bool>&& __vb);
848852# endif // _LIBCPP_CXX03_LANG
853 [[__nodiscard__]]
849854 _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr<const valarray&> > operator[](const valarray<size_t>& __vs) const;
850 _LIBCPP_HIDE_FROM_ABI indirect_array<value_type> operator[](const valarray<size_t>& __vs);
855 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI indirect_array<value_type> operator[](const valarray<size_t>& __vs);
851856# ifndef _LIBCPP_CXX03_LANG
857 [[__nodiscard__]]
852858 _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr<const valarray&> > operator[](valarray<size_t>&& __vs) const;
853 _LIBCPP_HIDE_FROM_ABI indirect_array<value_type> operator[](valarray<size_t>&& __vs);
859 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI indirect_array<value_type> operator[](valarray<size_t>&& __vs);
854860# endif // _LIBCPP_CXX03_LANG
855861
856862 // unary operators:
......@@ -904,16 +910,16 @@ public:
904910 // member functions:
905911 _LIBCPP_HIDE_FROM_ABI void swap(valarray& __v) _NOEXCEPT;
906912
907 _LIBCPP_HIDE_FROM_ABI size_t size() const { return static_cast<size_t>(__end_ - __begin_); }
913 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t size() const { return static_cast<size_t>(__end_ - __begin_); }
908914
909 _LIBCPP_HIDE_FROM_ABI value_type sum() const;
910 _LIBCPP_HIDE_FROM_ABI value_type min() const;
911 _LIBCPP_HIDE_FROM_ABI value_type max() const;
915 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_type sum() const;
916 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_type min() const;
917 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_type max() const;
912918
913 valarray shift(int __i) const;
914 valarray cshift(int __i) const;
915 valarray apply(value_type __f(value_type)) const;
916 valarray apply(value_type __f(const value_type&)) const;
919 [[__nodiscard__]] valarray shift(int __i) const;
920 [[__nodiscard__]] valarray cshift(int __i) const;
921 [[__nodiscard__]] valarray apply(value_type __f(value_type)) const;
922 [[__nodiscard__]] valarray apply(value_type __f(const value_type&)) const;
917923 void resize(size_t __n, value_type __x = value_type());
918924
919925private:
......@@ -1248,11 +1254,11 @@ public:
12481254
12491255# endif // _LIBCPP_CXX03_LANG
12501256
1251 _LIBCPP_HIDE_FROM_ABI size_t start() const { return __1d_.size() ? __1d_[0] : 0; }
1257 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t start() const { return __1d_.size() ? __1d_[0] : 0; }
12521258
1253 _LIBCPP_HIDE_FROM_ABI valarray<size_t> size() const { return __size_; }
1259 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI valarray<size_t> size() const { return __size_; }
12541260
1255 _LIBCPP_HIDE_FROM_ABI valarray<size_t> stride() const { return __stride_; }
1261 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI valarray<size_t> stride() const { return __stride_; }
12561262
12571263private:
12581264 void __init(size_t __start);
......@@ -1992,17 +1998,10 @@ template <class _Tp>
19921998inline valarray<_Tp>::valarray(size_t __n) : __begin_(nullptr), __end_(nullptr) {
19931999 if (__n) {
19942000 __begin_ = __end_ = allocator<value_type>().allocate(__n);
1995# if _LIBCPP_HAS_EXCEPTIONS
1996 try {
1997# endif // _LIBCPP_HAS_EXCEPTIONS
1998 for (size_t __n_left = __n; __n_left; --__n_left, ++__end_)
1999 ::new ((void*)__end_) value_type();
2000# if _LIBCPP_HAS_EXCEPTIONS
2001 } catch (...) {
2002 __clear(__n);
2003 throw;
2004 }
2005# endif // _LIBCPP_HAS_EXCEPTIONS
2001 auto __guard = std::__make_exception_guard([&] { __clear(__n); });
2002 for (size_t __n_left = __n; __n_left; --__n_left, ++__end_)
2003 ::new ((void*)__end_) value_type();
2004 __guard.__complete();
20062005 }
20072006}
20082007
......@@ -2015,17 +2014,10 @@ template <class _Tp>
20152014valarray<_Tp>::valarray(const value_type* __p, size_t __n) : __begin_(nullptr), __end_(nullptr) {
20162015 if (__n) {
20172016 __begin_ = __end_ = allocator<value_type>().allocate(__n);
2018# if _LIBCPP_HAS_EXCEPTIONS
2019 try {
2020# endif // _LIBCPP_HAS_EXCEPTIONS
2021 for (size_t __n_left = __n; __n_left; ++__end_, ++__p, --__n_left)
2022 ::new ((void*)__end_) value_type(*__p);
2023# if _LIBCPP_HAS_EXCEPTIONS
2024 } catch (...) {
2025 __clear(__n);
2026 throw;
2027 }
2028# endif // _LIBCPP_HAS_EXCEPTIONS
2017 auto __guard = std::__make_exception_guard([&] { __clear(__n); });
2018 for (size_t __n_left = __n; __n_left; ++__end_, ++__p, --__n_left)
2019 ::new ((void*)__end_) value_type(*__p);
2020 __guard.__complete();
20292021 }
20302022}
20312023
......@@ -2033,17 +2025,10 @@ template <class _Tp>
20332025valarray<_Tp>::valarray(const valarray& __v) : __begin_(nullptr), __end_(nullptr) {
20342026 if (__v.size()) {
20352027 __begin_ = __end_ = allocator<value_type>().allocate(__v.size());
2036# if _LIBCPP_HAS_EXCEPTIONS
2037 try {
2038# endif // _LIBCPP_HAS_EXCEPTIONS
2039 for (value_type* __p = __v.__begin_; __p != __v.__end_; ++__end_, ++__p)
2040 ::new ((void*)__end_) value_type(*__p);
2041# if _LIBCPP_HAS_EXCEPTIONS
2042 } catch (...) {
2043 __clear(__v.size());
2044 throw;
2045 }
2046# endif // _LIBCPP_HAS_EXCEPTIONS
2028 auto __guard = std::__make_exception_guard([&] { __clear(__v.size()); });
2029 for (value_type* __p = __v.__begin_; __p != __v.__end_; ++__end_, ++__p)
2030 ::new ((void*)__end_) value_type(*__p);
2031 __guard.__complete();
20472032 }
20482033}
20492034
......@@ -2059,18 +2044,11 @@ valarray<_Tp>::valarray(initializer_list<value_type> __il) : __begin_(nullptr),
20592044 const size_t __n = __il.size();
20602045 if (__n) {
20612046 __begin_ = __end_ = allocator<value_type>().allocate(__n);
2062# if _LIBCPP_HAS_EXCEPTIONS
2063 try {
2064# endif // _LIBCPP_HAS_EXCEPTIONS
2065 size_t __n_left = __n;
2066 for (const value_type* __p = __il.begin(); __n_left; ++__end_, ++__p, --__n_left)
2067 ::new ((void*)__end_) value_type(*__p);
2068# if _LIBCPP_HAS_EXCEPTIONS
2069 } catch (...) {
2070 __clear(__n);
2071 throw;
2072 }
2073# endif // _LIBCPP_HAS_EXCEPTIONS
2047 auto __guard = std::__make_exception_guard([&] { __clear(__n); });
2048 size_t __n_left = __n;
2049 for (const value_type* __p = __il.begin(); __n_left; ++__end_, ++__p, --__n_left)
2050 ::new ((void*)__end_) value_type(*__p);
2051 __guard.__complete();
20742052 }
20752053}
20762054
......@@ -2081,18 +2059,11 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa) : __begin_(nullptr)
20812059 const size_t __n = __sa.__size_;
20822060 if (__n) {
20832061 __begin_ = __end_ = allocator<value_type>().allocate(__n);
2084# if _LIBCPP_HAS_EXCEPTIONS
2085 try {
2086# endif // _LIBCPP_HAS_EXCEPTIONS
2087 size_t __n_left = __n;
2088 for (const value_type* __p = __sa.__vp_; __n_left; ++__end_, __p += __sa.__stride_, --__n_left)
2089 ::new ((void*)__end_) value_type(*__p);
2090# if _LIBCPP_HAS_EXCEPTIONS
2091 } catch (...) {
2092 __clear(__n);
2093 throw;
2094 }
2095# endif // _LIBCPP_HAS_EXCEPTIONS
2062 auto __guard = std::__make_exception_guard([&] { __clear(__n); });
2063 size_t __n_left = __n;
2064 for (const value_type* __p = __sa.__vp_; __n_left; ++__end_, __p += __sa.__stride_, --__n_left)
2065 ::new ((void*)__end_) value_type(*__p);
2066 __guard.__complete();
20962067 }
20972068}
20982069
......@@ -2101,19 +2072,12 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga) : __begin_(nullptr
21012072 const size_t __n = __ga.__1d_.size();
21022073 if (__n) {
21032074 __begin_ = __end_ = allocator<value_type>().allocate(__n);
2104# if _LIBCPP_HAS_EXCEPTIONS
2105 try {
2106# endif // _LIBCPP_HAS_EXCEPTIONS
2107 typedef const size_t* _Ip;
2108 const value_type* __s = __ga.__vp_;
2109 for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_; __i != __e; ++__i, ++__end_)
2110 ::new ((void*)__end_) value_type(__s[*__i]);
2111# if _LIBCPP_HAS_EXCEPTIONS
2112 } catch (...) {
2113 __clear(__n);
2114 throw;
2115 }
2116# endif // _LIBCPP_HAS_EXCEPTIONS
2075 auto __guard = std::__make_exception_guard([&] { __clear(__n); });
2076 typedef const size_t* _Ip;
2077 const value_type* __s = __ga.__vp_;
2078 for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_; __i != __e; ++__i, ++__end_)
2079 ::new ((void*)__end_) value_type(__s[*__i]);
2080 __guard.__complete();
21172081 }
21182082}
21192083
......@@ -2122,19 +2086,12 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma) : __begin_(nullptr),
21222086 const size_t __n = __ma.__1d_.size();
21232087 if (__n) {
21242088 __begin_ = __end_ = allocator<value_type>().allocate(__n);
2125# if _LIBCPP_HAS_EXCEPTIONS
2126 try {
2127# endif // _LIBCPP_HAS_EXCEPTIONS
2128 typedef const size_t* _Ip;
2129 const value_type* __s = __ma.__vp_;
2130 for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_; __i != __e; ++__i, ++__end_)
2131 ::new ((void*)__end_) value_type(__s[*__i]);
2132# if _LIBCPP_HAS_EXCEPTIONS
2133 } catch (...) {
2134 __clear(__n);
2135 throw;
2136 }
2137# endif // _LIBCPP_HAS_EXCEPTIONS
2089 auto __guard = std::__make_exception_guard([&] { __clear(__n); });
2090 typedef const size_t* _Ip;
2091 const value_type* __s = __ma.__vp_;
2092 for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_; __i != __e; ++__i, ++__end_)
2093 ::new ((void*)__end_) value_type(__s[*__i]);
2094 __guard.__complete();
21382095 }
21392096}
21402097
......@@ -2143,19 +2100,12 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia) : __begin_(nullp
21432100 const size_t __n = __ia.__1d_.size();
21442101 if (__n) {
21452102 __begin_ = __end_ = allocator<value_type>().allocate(__n);
2146# if _LIBCPP_HAS_EXCEPTIONS
2147 try {
2148# endif // _LIBCPP_HAS_EXCEPTIONS
2149 typedef const size_t* _Ip;
2150 const value_type* __s = __ia.__vp_;
2151 for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_; __i != __e; ++__i, ++__end_)
2152 ::new ((void*)__end_) value_type(__s[*__i]);
2153# if _LIBCPP_HAS_EXCEPTIONS
2154 } catch (...) {
2155 __clear(__n);
2156 throw;
2157 }
2158# endif // _LIBCPP_HAS_EXCEPTIONS
2103 auto __guard = std::__make_exception_guard([&] { __clear(__n); });
2104 typedef const size_t* _Ip;
2105 const value_type* __s = __ia.__vp_;
2106 for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_; __i != __e; ++__i, ++__end_)
2107 ::new ((void*)__end_) value_type(__s[*__i]);
2108 __guard.__complete();
21592109 }
21602110}
21612111
......@@ -2644,17 +2594,10 @@ void valarray<_Tp>::resize(size_t __n, value_type __x) {
26442594 __clear(size());
26452595 if (__n) {
26462596 __begin_ = __end_ = allocator<value_type>().allocate(__n);
2647# if _LIBCPP_HAS_EXCEPTIONS
2648 try {
2649# endif // _LIBCPP_HAS_EXCEPTIONS
2650 for (size_t __n_left = __n; __n_left; --__n_left, ++__end_)
2651 ::new ((void*)__end_) value_type(__x);
2652# if _LIBCPP_HAS_EXCEPTIONS
2653 } catch (...) {
2654 __clear(__n);
2655 throw;
2656 }
2657# endif // _LIBCPP_HAS_EXCEPTIONS
2597 auto __guard = std::__make_exception_guard([&] { __clear(__n); });
2598 for (size_t __n_left = __n; __n_left; --__n_left, ++__end_)
2599 ::new ((void*)__end_) value_type(__x);
2600 __guard.__complete();
26582601 }
26592602}
26602603
......@@ -3168,7 +3111,7 @@ operator>=(const typename _Expr::value_type& __x, const _Expr& __y) {
31683111}
31693112
31703113template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3171inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__abs_expr<typename _Expr::value_type>, _Expr> >
3114[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__abs_expr<typename _Expr::value_type>, _Expr> >
31723115abs(const _Expr& __x) {
31733116 typedef typename _Expr::value_type value_type;
31743117 typedef _UnaryOp<__abs_expr<value_type>, _Expr> _Op;
......@@ -3176,7 +3119,7 @@ abs(const _Expr& __x) {
31763119}
31773120
31783121template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3179inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__acos_expr<typename _Expr::value_type>, _Expr> >
3122[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__acos_expr<typename _Expr::value_type>, _Expr> >
31803123acos(const _Expr& __x) {
31813124 typedef typename _Expr::value_type value_type;
31823125 typedef _UnaryOp<__acos_expr<value_type>, _Expr> _Op;
......@@ -3184,7 +3127,7 @@ acos(const _Expr& __x) {
31843127}
31853128
31863129template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3187inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__asin_expr<typename _Expr::value_type>, _Expr> >
3130[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__asin_expr<typename _Expr::value_type>, _Expr> >
31883131asin(const _Expr& __x) {
31893132 typedef typename _Expr::value_type value_type;
31903133 typedef _UnaryOp<__asin_expr<value_type>, _Expr> _Op;
......@@ -3192,7 +3135,7 @@ asin(const _Expr& __x) {
31923135}
31933136
31943137template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3195inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__atan_expr<typename _Expr::value_type>, _Expr> >
3138[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__atan_expr<typename _Expr::value_type>, _Expr> >
31963139atan(const _Expr& __x) {
31973140 typedef typename _Expr::value_type value_type;
31983141 typedef _UnaryOp<__atan_expr<value_type>, _Expr> _Op;
......@@ -3202,15 +3145,16 @@ atan(const _Expr& __x) {
32023145template <class _Expr1,
32033146 class _Expr2,
32043147 __enable_if_t<__is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, int> = 0>
3205inline _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__atan2_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
3206atan2(const _Expr1& __x, const _Expr2& __y) {
3148[[__nodiscard__]] inline
3149 _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__atan2_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
3150 atan2(const _Expr1& __x, const _Expr2& __y) {
32073151 typedef typename _Expr1::value_type value_type;
32083152 typedef _BinaryOp<__atan2_expr<value_type>, _Expr1, _Expr2> _Op;
32093153 return __val_expr<_Op>(_Op(__atan2_expr<value_type>(), __x, __y));
32103154}
32113155
32123156template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3213inline _LIBCPP_HIDE_FROM_ABI
3157[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
32143158__val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>, _Expr, __scalar_expr<typename _Expr::value_type> > >
32153159atan2(const _Expr& __x, const typename _Expr::value_type& __y) {
32163160 typedef typename _Expr::value_type value_type;
......@@ -3219,7 +3163,7 @@ atan2(const _Expr& __x, const typename _Expr::value_type& __y) {
32193163}
32203164
32213165template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3222inline _LIBCPP_HIDE_FROM_ABI
3166[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
32233167__val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>, __scalar_expr<typename _Expr::value_type>, _Expr> >
32243168atan2(const typename _Expr::value_type& __x, const _Expr& __y) {
32253169 typedef typename _Expr::value_type value_type;
......@@ -3228,7 +3172,7 @@ atan2(const typename _Expr::value_type& __x, const _Expr& __y) {
32283172}
32293173
32303174template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3231inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__cos_expr<typename _Expr::value_type>, _Expr> >
3175[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__cos_expr<typename _Expr::value_type>, _Expr> >
32323176cos(const _Expr& __x) {
32333177 typedef typename _Expr::value_type value_type;
32343178 typedef _UnaryOp<__cos_expr<value_type>, _Expr> _Op;
......@@ -3236,7 +3180,7 @@ cos(const _Expr& __x) {
32363180}
32373181
32383182template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3239inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__cosh_expr<typename _Expr::value_type>, _Expr> >
3183[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__cosh_expr<typename _Expr::value_type>, _Expr> >
32403184cosh(const _Expr& __x) {
32413185 typedef typename _Expr::value_type value_type;
32423186 typedef _UnaryOp<__cosh_expr<value_type>, _Expr> _Op;
......@@ -3244,7 +3188,7 @@ cosh(const _Expr& __x) {
32443188}
32453189
32463190template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3247inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__exp_expr<typename _Expr::value_type>, _Expr> >
3191[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__exp_expr<typename _Expr::value_type>, _Expr> >
32483192exp(const _Expr& __x) {
32493193 typedef typename _Expr::value_type value_type;
32503194 typedef _UnaryOp<__exp_expr<value_type>, _Expr> _Op;
......@@ -3252,7 +3196,7 @@ exp(const _Expr& __x) {
32523196}
32533197
32543198template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3255inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__log_expr<typename _Expr::value_type>, _Expr> >
3199[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__log_expr<typename _Expr::value_type>, _Expr> >
32563200log(const _Expr& __x) {
32573201 typedef typename _Expr::value_type value_type;
32583202 typedef _UnaryOp<__log_expr<value_type>, _Expr> _Op;
......@@ -3260,7 +3204,7 @@ log(const _Expr& __x) {
32603204}
32613205
32623206template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3263inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__log10_expr<typename _Expr::value_type>, _Expr> >
3207[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__log10_expr<typename _Expr::value_type>, _Expr> >
32643208log10(const _Expr& __x) {
32653209 typedef typename _Expr::value_type value_type;
32663210 typedef _UnaryOp<__log10_expr<value_type>, _Expr> _Op;
......@@ -3270,15 +3214,16 @@ log10(const _Expr& __x) {
32703214template <class _Expr1,
32713215 class _Expr2,
32723216 __enable_if_t<__is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, int> = 0>
3273inline _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__pow_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
3274pow(const _Expr1& __x, const _Expr2& __y) {
3217[[__nodiscard__]] inline
3218 _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__pow_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
3219 pow(const _Expr1& __x, const _Expr2& __y) {
32753220 typedef typename _Expr1::value_type value_type;
32763221 typedef _BinaryOp<__pow_expr<value_type>, _Expr1, _Expr2> _Op;
32773222 return __val_expr<_Op>(_Op(__pow_expr<value_type>(), __x, __y));
32783223}
32793224
32803225template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3281inline _LIBCPP_HIDE_FROM_ABI
3226[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
32823227__val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>, _Expr, __scalar_expr<typename _Expr::value_type> > >
32833228pow(const _Expr& __x, const typename _Expr::value_type& __y) {
32843229 typedef typename _Expr::value_type value_type;
......@@ -3287,7 +3232,7 @@ pow(const _Expr& __x, const typename _Expr::value_type& __y) {
32873232}
32883233
32893234template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3290inline _LIBCPP_HIDE_FROM_ABI
3235[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
32913236__val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>, __scalar_expr<typename _Expr::value_type>, _Expr> >
32923237pow(const typename _Expr::value_type& __x, const _Expr& __y) {
32933238 typedef typename _Expr::value_type value_type;
......@@ -3296,7 +3241,7 @@ pow(const typename _Expr::value_type& __x, const _Expr& __y) {
32963241}
32973242
32983243template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3299inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sin_expr<typename _Expr::value_type>, _Expr> >
3244[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sin_expr<typename _Expr::value_type>, _Expr> >
33003245sin(const _Expr& __x) {
33013246 typedef typename _Expr::value_type value_type;
33023247 typedef _UnaryOp<__sin_expr<value_type>, _Expr> _Op;
......@@ -3304,7 +3249,7 @@ sin(const _Expr& __x) {
33043249}
33053250
33063251template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3307inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sinh_expr<typename _Expr::value_type>, _Expr> >
3252[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sinh_expr<typename _Expr::value_type>, _Expr> >
33083253sinh(const _Expr& __x) {
33093254 typedef typename _Expr::value_type value_type;
33103255 typedef _UnaryOp<__sinh_expr<value_type>, _Expr> _Op;
......@@ -3312,7 +3257,7 @@ sinh(const _Expr& __x) {
33123257}
33133258
33143259template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3315inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sqrt_expr<typename _Expr::value_type>, _Expr> >
3260[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sqrt_expr<typename _Expr::value_type>, _Expr> >
33163261sqrt(const _Expr& __x) {
33173262 typedef typename _Expr::value_type value_type;
33183263 typedef _UnaryOp<__sqrt_expr<value_type>, _Expr> _Op;
......@@ -3320,7 +3265,7 @@ sqrt(const _Expr& __x) {
33203265}
33213266
33223267template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3323inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__tan_expr<typename _Expr::value_type>, _Expr> >
3268[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__tan_expr<typename _Expr::value_type>, _Expr> >
33243269tan(const _Expr& __x) {
33253270 typedef typename _Expr::value_type value_type;
33263271 typedef _UnaryOp<__tan_expr<value_type>, _Expr> _Op;
......@@ -3328,7 +3273,7 @@ tan(const _Expr& __x) {
33283273}
33293274
33303275template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
3331inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__tanh_expr<typename _Expr::value_type>, _Expr> >
3276[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__tanh_expr<typename _Expr::value_type>, _Expr> >
33323277tanh(const _Expr& __x) {
33333278 typedef typename _Expr::value_type value_type;
33343279 typedef _UnaryOp<__tanh_expr<value_type>, _Expr> _Op;
......@@ -3336,22 +3281,22 @@ tanh(const _Expr& __x) {
33363281}
33373282
33383283template <class _Tp>
3339inline _LIBCPP_HIDE_FROM_ABI _Tp* begin(valarray<_Tp>& __v) {
3284[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Tp* begin(valarray<_Tp>& __v) {
33403285 return __v.__begin_;
33413286}
33423287
33433288template <class _Tp>
3344inline _LIBCPP_HIDE_FROM_ABI const _Tp* begin(const valarray<_Tp>& __v) {
3289[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI const _Tp* begin(const valarray<_Tp>& __v) {
33453290 return __v.__begin_;
33463291}
33473292
33483293template <class _Tp>
3349inline _LIBCPP_HIDE_FROM_ABI _Tp* end(valarray<_Tp>& __v) {
3294[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Tp* end(valarray<_Tp>& __v) {
33503295 return __v.__end_;
33513296}
33523297
33533298template <class _Tp>
3354inline _LIBCPP_HIDE_FROM_ABI const _Tp* end(const valarray<_Tp>& __v) {
3299[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI const _Tp* end(const valarray<_Tp>& __v) {
33553300 return __v.__end_;
33563301}
33573302
lib/libcxx/include/variant+25-33
......@@ -247,7 +247,6 @@ namespace std {
247247# include <__type_traits/is_nothrow_assignable.h>
248248# include <__type_traits/is_nothrow_constructible.h>
249249# include <__type_traits/is_reference.h>
250# include <__type_traits/is_replaceable.h>
251250# include <__type_traits/is_same.h>
252251# include <__type_traits/is_swappable.h>
253252# include <__type_traits/is_trivially_assignable.h>
......@@ -289,7 +288,7 @@ _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
289288
290289class _LIBCPP_EXPORTED_FROM_ABI bad_variant_access : public exception {
291290public:
292 const char* what() const _NOEXCEPT override;
291 [[__nodiscard__]] const char* what() const _NOEXCEPT override;
293292};
294293
295294_LIBCPP_END_UNVERSIONED_NAMESPACE_STD
......@@ -918,18 +917,10 @@ protected:
918917 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
919918 if (this->index() == _Ip) {
920919 __a.__value = std::forward<_Arg>(__arg);
920 } else if constexpr (is_nothrow_constructible_v<_Tp, _Arg> || !is_nothrow_move_constructible_v<_Tp>) {
921 this->__emplace<_Ip>(std::forward<_Arg>(__arg));
921922 } else {
922 struct {
923 _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(true_type) const {
924 __this->__emplace<_Ip>(std::forward<_Arg>(__arg));
925 }
926 _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(false_type) const {
927 __this->__emplace<_Ip>(_Tp(std::forward<_Arg>(__arg)));
928 }
929 __assignment* __this;
930 _Arg&& __arg;
931 } __impl{this, std::forward<_Arg>(__arg)};
932 __impl(bool_constant < is_nothrow_constructible_v<_Tp, _Arg> || !is_nothrow_move_constructible_v < _Tp >> {});
923 this->__emplace<_Ip>(_Tp(std::forward<_Arg>(__arg)));
933924 }
934925 }
935926
......@@ -1127,14 +1118,14 @@ template <class _IdxSeq>
11271118struct __make_overloads_imp;
11281119
11291120template <size_t... _Idx>
1130struct __make_overloads_imp<__tuple_indices<_Idx...> > {
1121struct __make_overloads_imp<index_sequence<_Idx...> > {
11311122 template <class... _Types>
11321123 using _Apply _LIBCPP_NODEBUG = __all_overloads<__overload<_Types, _Idx>...>;
11331124};
11341125
11351126template <class... _Types>
11361127using _MakeOverloads _LIBCPP_NODEBUG =
1137 typename __make_overloads_imp< __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>;
1128 typename __make_overloads_imp<make_index_sequence<sizeof...(_Types)>>::template _Apply<_Types...>;
11381129
11391130template <class _Tp, class... _Types>
11401131using __best_match_t _LIBCPP_NODEBUG = typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type;
......@@ -1172,7 +1163,6 @@ class _LIBCPP_DECLSPEC_EMPTY_BASES _LIBCPP_NO_SPECIALIZATIONS variant
11721163public:
11731164 using __trivially_relocatable _LIBCPP_NODEBUG =
11741165 conditional_t<_And<__libcpp_is_trivially_relocatable<_Types>...>::value, variant, void>;
1175 using __replaceable _LIBCPP_NODEBUG = conditional_t<_And<__is_replaceable<_Types>...>::value, variant, void>;
11761166
11771167 template <bool _Dummy = true,
11781168 enable_if_t<__dependent_type<is_default_constructible<__first_type>, _Dummy>::value, int> = 0>
......@@ -1284,11 +1274,11 @@ public:
12841274 return __impl_.template __emplace<_Ip>(__il, std::forward<_Args>(__args)...);
12851275 }
12861276
1287 _LIBCPP_HIDE_FROM_ABI constexpr bool valueless_by_exception() const noexcept {
1277 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool valueless_by_exception() const noexcept {
12881278 return __impl_.valueless_by_exception();
12891279 }
12901280
1291 _LIBCPP_HIDE_FROM_ABI constexpr size_t index() const noexcept { return __impl_.index(); }
1281 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t index() const noexcept { return __impl_.index(); }
12921282
12931283 template < bool _Dummy = true,
12941284 enable_if_t< __all<(__dependent_type<is_move_constructible<_Types>, _Dummy>::value &&
......@@ -1299,7 +1289,7 @@ public:
12991289 __impl_.__swap(__that.__impl_);
13001290 }
13011291
1302# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
1292# if _LIBCPP_STD_VER >= 26
13031293 // Helper class to implement [variant.visit]/10
13041294 // Constraints: The call to visit does not use an explicit template-argument-list
13051295 // that begins with a type template-argument.
......@@ -1331,7 +1321,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __holds_alternative(const variant<_Types...
13311321}
13321322
13331323template <class _Tp, class... _Types>
1334_LIBCPP_HIDE_FROM_ABI constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
1324[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
13351325 return std::__holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
13361326}
13371327
......@@ -1345,21 +1335,23 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto&& __generic_get(_Vp&& __v) {
13451335}
13461336
13471337template <size_t _Ip, class... _Types>
1348_LIBCPP_HIDE_FROM_ABI constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(variant<_Types...>& __v) {
1338[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr variant_alternative_t<_Ip, variant<_Types...>>&
1339get(variant<_Types...>& __v) {
13491340 static_assert(_Ip < sizeof...(_Types));
13501341 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
13511342 return std::__generic_get<_Ip>(__v);
13521343}
13531344
13541345template <size_t _Ip, class... _Types>
1355_LIBCPP_HIDE_FROM_ABI constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(variant<_Types...>&& __v) {
1346[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr variant_alternative_t<_Ip, variant<_Types...>>&&
1347get(variant<_Types...>&& __v) {
13561348 static_assert(_Ip < sizeof...(_Types));
13571349 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
13581350 return std::__generic_get<_Ip>(std::move(__v));
13591351}
13601352
13611353template <size_t _Ip, class... _Types>
1362_LIBCPP_HIDE_FROM_ABI constexpr const variant_alternative_t<_Ip, variant<_Types...>>&
1354[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const variant_alternative_t<_Ip, variant<_Types...>>&
13631355get(const variant<_Types...>& __v) {
13641356 static_assert(_Ip < sizeof...(_Types));
13651357 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
......@@ -1367,7 +1359,7 @@ get(const variant<_Types...>& __v) {
13671359}
13681360
13691361template <size_t _Ip, class... _Types>
1370_LIBCPP_HIDE_FROM_ABI constexpr const variant_alternative_t<_Ip, variant<_Types...>>&&
1362[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const variant_alternative_t<_Ip, variant<_Types...>>&&
13711363get(const variant<_Types...>&& __v) {
13721364 static_assert(_Ip < sizeof...(_Types));
13731365 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
......@@ -1375,25 +1367,25 @@ get(const variant<_Types...>&& __v) {
13751367}
13761368
13771369template <class _Tp, class... _Types>
1378_LIBCPP_HIDE_FROM_ABI constexpr _Tp& get(variant<_Types...>& __v) {
1370[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp& get(variant<_Types...>& __v) {
13791371 static_assert(!is_void_v<_Tp>);
13801372 return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
13811373}
13821374
13831375template <class _Tp, class... _Types>
1384_LIBCPP_HIDE_FROM_ABI constexpr _Tp&& get(variant<_Types...>&& __v) {
1376[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& get(variant<_Types...>&& __v) {
13851377 static_assert(!is_void_v<_Tp>);
13861378 return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(std::move(__v));
13871379}
13881380
13891381template <class _Tp, class... _Types>
1390_LIBCPP_HIDE_FROM_ABI constexpr const _Tp& get(const variant<_Types...>& __v) {
1382[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& get(const variant<_Types...>& __v) {
13911383 static_assert(!is_void_v<_Tp>);
13921384 return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
13931385}
13941386
13951387template <class _Tp, class... _Types>
1396_LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& get(const variant<_Types...>&& __v) {
1388[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& get(const variant<_Types...>&& __v) {
13971389 static_assert(!is_void_v<_Tp>);
13981390 return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(std::move(__v));
13991391}
......@@ -1405,7 +1397,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto* __generic_get_if(_Vp* __v) noexcept {
14051397}
14061398
14071399template <size_t _Ip, class... _Types>
1408_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
1400[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
14091401get_if(variant<_Types...>* __v) noexcept {
14101402 static_assert(_Ip < sizeof...(_Types));
14111403 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
......@@ -1413,7 +1405,7 @@ get_if(variant<_Types...>* __v) noexcept {
14131405}
14141406
14151407template <size_t _Ip, class... _Types>
1416_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
1408[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
14171409get_if(const variant<_Types...>* __v) noexcept {
14181410 static_assert(_Ip < sizeof...(_Types));
14191411 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
......@@ -1421,13 +1413,13 @@ get_if(const variant<_Types...>* __v) noexcept {
14211413}
14221414
14231415template <class _Tp, class... _Types>
1424_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp> get_if(variant<_Types...>* __v) noexcept {
1416[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp> get_if(variant<_Types...>* __v) noexcept {
14251417 static_assert(!is_void_v<_Tp>);
14261418 return std::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
14271419}
14281420
14291421template <class _Tp, class... _Types>
1430_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<const _Tp> get_if(const variant<_Types...>* __v) noexcept {
1422[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<const _Tp> get_if(const variant<_Types...>* __v) noexcept {
14311423 static_assert(!is_void_v<_Tp>);
14321424 return std::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
14331425}
......@@ -1608,7 +1600,7 @@ struct hash< __enable_hash_helper<variant<_Types...>, remove_const_t<_Types>...>
16081600 using result_type _LIBCPP_DEPRECATED_IN_CXX17 = size_t;
16091601# endif
16101602
1611 _LIBCPP_HIDE_FROM_ABI size_t operator()(const variant<_Types...>& __v) const {
1603 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const variant<_Types...>& __v) const {
16121604 using __variant_detail::__visitation::__variant;
16131605 size_t __res =
16141606 __v.valueless_by_exception()
lib/libcxx/include/version+41-24
......@@ -37,7 +37,8 @@ __cpp_lib_atomic_float 201711L <atomic>
3737__cpp_lib_atomic_is_always_lock_free 201603L <atomic>
3838__cpp_lib_atomic_lock_free_type_aliases 201907L <atomic>
3939__cpp_lib_atomic_min_max 202403L <atomic>
40__cpp_lib_atomic_ref 201806L <atomic>
40__cpp_lib_atomic_ref 202411L <atomic>
41 201806L // C++20
4142__cpp_lib_atomic_shared_ptr 201711L <atomic>
4243__cpp_lib_atomic_value_initialization 201911L <atomic> <memory>
4344__cpp_lib_atomic_wait 201907L <atomic>
......@@ -62,7 +63,7 @@ __cpp_lib_clamp 201603L <algorithm>
6263__cpp_lib_common_reference 202302L <type_traits>
6364__cpp_lib_common_reference_wrapper 202302L <functional>
6465__cpp_lib_complex_udls 201309L <complex>
65__cpp_lib_concepts 202002L <concepts>
66__cpp_lib_concepts 202207L <concepts>
6667__cpp_lib_constexpr_algorithms 202306L <algorithm> <utility>
6768 201806L // C++20
6869__cpp_lib_constexpr_bitset 202207L <bitset>
......@@ -70,6 +71,8 @@ __cpp_lib_constexpr_charconv 202207L <charconv>
7071__cpp_lib_constexpr_cmath 202202L <cmath> <cstdlib>
7172__cpp_lib_constexpr_complex 201711L <complex>
7273__cpp_lib_constexpr_dynamic_alloc 201907L <memory>
74__cpp_lib_constexpr_flat_map 202502L <flat_map>
75__cpp_lib_constexpr_flat_set 202502L <flat_set>
7376__cpp_lib_constexpr_forward_list 202502L <forward_list>
7477__cpp_lib_constexpr_functional 201907L <functional>
7578__cpp_lib_constexpr_iterator 201811L <iterator>
......@@ -108,8 +111,8 @@ __cpp_lib_execution 201902L <execution>
108111 201603L // C++17
109112__cpp_lib_expected 202211L <expected>
110113__cpp_lib_filesystem 201703L <filesystem>
111__cpp_lib_flat_map 202207L <flat_map>
112__cpp_lib_flat_set 202207L <flat_set>
114__cpp_lib_flat_map 202511L <flat_map>
115__cpp_lib_flat_set 202511L <flat_set>
113116__cpp_lib_format 202110L <format>
114117__cpp_lib_format_path 202403L <filesystem>
115118__cpp_lib_format_ranges 202207L <format>
......@@ -138,7 +141,8 @@ __cpp_lib_incomplete_container_elements 201505L <forward_list> <
138141__cpp_lib_inplace_vector 202406L <inplace_vector>
139142__cpp_lib_int_pow2 202002L <bit>
140143__cpp_lib_integer_comparison_functions 202002L <utility>
141__cpp_lib_integer_sequence 201304L <utility>
144__cpp_lib_integer_sequence 202511L <utility>
145 201304L // C++14
142146__cpp_lib_integral_constant_callable 201304L <type_traits>
143147__cpp_lib_interpolate 201902L <cmath> <numeric>
144148__cpp_lib_invoke 201411L <functional>
......@@ -184,7 +188,8 @@ __cpp_lib_nonmember_container_access 201411L <array> <deque>
184188__cpp_lib_not_fn 202306L <functional>
185189 201603L // C++17
186190__cpp_lib_null_iterators 201304L <iterator>
187__cpp_lib_optional 202110L <optional>
191__cpp_lib_optional 202506L <optional>
192 202110L // C++23
188193 202106L // C++20
189194 201606L // C++17
190195__cpp_lib_optional_range_support 202406L <optional>
......@@ -205,6 +210,7 @@ __cpp_lib_ranges_chunk_by 202202L <ranges>
205210__cpp_lib_ranges_concat 202403L <ranges>
206211__cpp_lib_ranges_contains 202207L <algorithm>
207212__cpp_lib_ranges_find_last 202207L <algorithm>
213__cpp_lib_ranges_indices 202506L <ranges>
208214__cpp_lib_ranges_iota 202202L <numeric>
209215__cpp_lib_ranges_join_with 202202L <ranges>
210216__cpp_lib_ranges_repeat 202207L <ranges>
......@@ -245,6 +251,7 @@ __cpp_lib_starts_ends_with 201711L <string> <string
245251__cpp_lib_stdatomic_h 202011L <stdatomic.h>
246252__cpp_lib_string_contains 202011L <string> <string_view>
247253__cpp_lib_string_resize_and_overwrite 202110L <string>
254__cpp_lib_string_subview 202506L <string> <string_view>
248255__cpp_lib_string_udls 201304L <string>
249256__cpp_lib_string_view 202403L <string> <string_view>
250257 201803L // C++20
......@@ -333,13 +340,11 @@ __cpp_lib_void_t 201411L <type_traits>
333340# define __cpp_lib_clamp 201603L
334341# define __cpp_lib_enable_shared_from_this 201603L
335342// # define __cpp_lib_execution 201603L
336# if _LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY
343# if _LIBCPP_HAS_FILESYSTEM
337344# define __cpp_lib_filesystem 201703L
338345# endif
339346# define __cpp_lib_gcd_lcm 201606L
340# if defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
341# define __cpp_lib_hardware_interference_size 201703L
342# endif
347# define __cpp_lib_hardware_interference_size 201703L
343348# define __cpp_lib_has_unique_object_representations 201606L
344349# define __cpp_lib_hypot 201603L
345350# define __cpp_lib_incomplete_container_elements 201505L
......@@ -391,10 +396,8 @@ __cpp_lib_void_t 201411L <type_traits>
391396# define __cpp_lib_atomic_ref 201806L
392397// # define __cpp_lib_atomic_shared_ptr 201711L
393398# define __cpp_lib_atomic_value_initialization 201911L
394# if _LIBCPP_AVAILABILITY_HAS_SYNC
395# define __cpp_lib_atomic_wait 201907L
396# endif
397# if _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC
399# define __cpp_lib_atomic_wait 201907L
400# if _LIBCPP_HAS_THREADS
398401# define __cpp_lib_barrier 201907L
399402# endif
400403# define __cpp_lib_bind_front 201907L
......@@ -406,7 +409,7 @@ __cpp_lib_void_t 201411L <type_traits>
406409# endif
407410# define __cpp_lib_common_reference 202302L
408411# define __cpp_lib_common_reference_wrapper 202302L
409# define __cpp_lib_concepts 202002L
412# define __cpp_lib_concepts 202207L
410413# define __cpp_lib_constexpr_algorithms 201806L
411414# define __cpp_lib_constexpr_complex 201711L
412415# define __cpp_lib_constexpr_dynamic_alloc 201907L
......@@ -439,10 +442,10 @@ __cpp_lib_void_t 201411L <type_traits>
439442// # define __cpp_lib_is_layout_compatible 201907L
440443# define __cpp_lib_is_nothrow_convertible 201806L
441444// # define __cpp_lib_is_pointer_interconvertible 201907L
442# if _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC
445# if _LIBCPP_HAS_THREADS
443446# define __cpp_lib_jthread 201911L
444447# endif
445# if _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC
448# if _LIBCPP_HAS_THREADS
446449# define __cpp_lib_latch 201907L
447450# endif
448451# define __cpp_lib_list_remove_return_type 201806L
......@@ -455,7 +458,7 @@ __cpp_lib_void_t 201411L <type_traits>
455458# endif
456459# define __cpp_lib_ranges 202110L
457460# define __cpp_lib_remove_cvref 201711L
458# if _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC
461# if _LIBCPP_HAS_THREADS
459462# define __cpp_lib_semaphore 201907L
460463# endif
461464# undef __cpp_lib_shared_ptr_arrays
......@@ -494,8 +497,8 @@ __cpp_lib_void_t 201411L <type_traits>
494497# define __cpp_lib_constexpr_typeinfo 202106L
495498# define __cpp_lib_containers_ranges 202202L
496499# define __cpp_lib_expected 202211L
497# define __cpp_lib_flat_map 202207L
498# define __cpp_lib_flat_set 202207L
500# define __cpp_lib_flat_map 202511L
501# define __cpp_lib_flat_set 202511L
499502# define __cpp_lib_format_ranges 202207L
500503// # define __cpp_lib_formatters 202302L
501504# define __cpp_lib_forward_like 202207L
......@@ -528,7 +531,7 @@ __cpp_lib_void_t 201411L <type_traits>
528531// # define __cpp_lib_ranges_slide 202202L
529532# define __cpp_lib_ranges_starts_ends_with 202106L
530533# define __cpp_lib_ranges_to_container 202202L
531// # define __cpp_lib_ranges_zip 202110L
534# define __cpp_lib_ranges_zip 202110L
532535// # define __cpp_lib_reference_from_temporary 202202L
533536// # define __cpp_lib_spanstream 202106L
534537// # define __cpp_lib_stacktrace 202011L
......@@ -544,18 +547,22 @@ __cpp_lib_void_t 201411L <type_traits>
544547# define __cpp_lib_aligned_accessor 202411L
545548// # define __cpp_lib_associative_heterogeneous_insertion 202306L
546549// # define __cpp_lib_atomic_min_max 202403L
550# undef __cpp_lib_atomic_ref
551# define __cpp_lib_atomic_ref 202411L
547552# undef __cpp_lib_bind_front
548553# define __cpp_lib_bind_front 202306L
549554# define __cpp_lib_bitset 202306L
550555# undef __cpp_lib_constexpr_algorithms
551556# define __cpp_lib_constexpr_algorithms 202306L
557# define __cpp_lib_constexpr_flat_map 202502L
558# define __cpp_lib_constexpr_flat_set 202502L
552559# define __cpp_lib_constexpr_forward_list 202502L
553560# define __cpp_lib_constexpr_list 202502L
554561# if !defined(_LIBCPP_ABI_VCRUNTIME)
555562# define __cpp_lib_constexpr_new 202406L
556563# endif
557564# define __cpp_lib_constexpr_queue 202502L
558// # define __cpp_lib_constrained_equality 202411L
565# define __cpp_lib_constrained_equality 202411L
559566// # define __cpp_lib_copyable_function 202306L
560567// # define __cpp_lib_debugging 202311L
561568// # define __cpp_lib_default_template_type_for_algorithm_values 202403L
......@@ -575,21 +582,30 @@ __cpp_lib_void_t 201411L <type_traits>
575582// # define __cpp_lib_generate_random 202403L
576583// # define __cpp_lib_hazard_pointer 202306L
577584// # define __cpp_lib_inplace_vector 202406L
585# undef __cpp_lib_integer_sequence
586# define __cpp_lib_integer_sequence 202511L
578587# define __cpp_lib_is_sufficiently_aligned 202411L
579588# if __has_builtin(__builtin_is_virtual_base_of)
580589# define __cpp_lib_is_virtual_base_of 202406L
581590# endif
582// # define __cpp_lib_is_within_lifetime 202306L
591# if __has_builtin(__builtin_is_within_lifetime)
592# define __cpp_lib_is_within_lifetime 202306L
593# endif
583594// # define __cpp_lib_linalg 202311L
584595# undef __cpp_lib_mdspan
585596# define __cpp_lib_mdspan 202406L
586597# undef __cpp_lib_not_fn
587598# define __cpp_lib_not_fn 202306L
588// # define __cpp_lib_optional_range_support 202406L
599# undef __cpp_lib_optional
600# define __cpp_lib_optional 202506L
601# if _LIBCPP_HAS_EXPERIMENTAL_OPTIONAL_ITERATOR
602# define __cpp_lib_optional_range_support 202406L
603# endif
589604# undef __cpp_lib_out_ptr
590605# define __cpp_lib_out_ptr 202311L
591606// # define __cpp_lib_philox_engine 202406L
592607// # define __cpp_lib_ranges_concat 202403L
608# define __cpp_lib_ranges_indices 202506L
593609# define __cpp_lib_ratio 202306L
594610// # define __cpp_lib_rcu 202306L
595611# define __cpp_lib_reference_wrapper 202403L
......@@ -599,6 +615,7 @@ __cpp_lib_void_t 201411L <type_traits>
599615# define __cpp_lib_span_at 202311L
600616# define __cpp_lib_span_initializer_list 202311L
601617# define __cpp_lib_sstream_from_string_view 202306L
618# define __cpp_lib_string_subview 202506L
602619# undef __cpp_lib_string_view
603620# define __cpp_lib_string_view 202403L
604621// # define __cpp_lib_submdspan 202306L
lib/libcxx/include/wctype.h+29-29
......@@ -45,13 +45,14 @@ wctrans_t wctrans(const char* property);
4545*/
4646
4747#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
48# include <__cxx03/wctype.h>
48# include <__cxx03/__config>
4949#else
5050# include <__config>
51#endif
5152
52# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
53# pragma GCC system_header
54# endif
53#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
54# pragma GCC system_header
55#endif
5556
5657// TODO:
5758// In the future, we should unconditionally include_next <wctype.h> here and instead
......@@ -62,33 +63,32 @@ wctrans_t wctrans(const char* property);
6263// nothing (with using_if_exists), and if we include another header that defines one
6364// of these declarations (e.g. <wchar.h>), the second `using ::wint_t` with using_if_exists
6465// will fail because it does not refer to the same declaration.
65# if __has_include_next(<wctype.h>)
66# include_next <wctype.h>
67# define _LIBCPP_INCLUDED_C_LIBRARY_WCTYPE_H
68# endif
66#if __has_include_next(<wctype.h>)
67# include_next <wctype.h>
68# define _LIBCPP_INCLUDED_C_LIBRARY_WCTYPE_H
69#endif
6970
70# ifdef __cplusplus
71#ifdef __cplusplus
7172
72# undef iswalnum
73# undef iswalpha
74# undef iswblank
75# undef iswcntrl
76# undef iswdigit
77# undef iswgraph
78# undef iswlower
79# undef iswprint
80# undef iswpunct
81# undef iswspace
82# undef iswupper
83# undef iswxdigit
84# undef iswctype
85# undef wctype
86# undef towlower
87# undef towupper
88# undef towctrans
89# undef wctrans
73# undef iswalnum
74# undef iswalpha
75# undef iswblank
76# undef iswcntrl
77# undef iswdigit
78# undef iswgraph
79# undef iswlower
80# undef iswprint
81# undef iswpunct
82# undef iswspace
83# undef iswupper
84# undef iswxdigit
85# undef iswctype
86# undef wctype
87# undef towlower
88# undef towupper
89# undef towctrans
90# undef wctrans
9091
91# endif // __cplusplus
92#endif // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
92#endif // __cplusplus
9393
9494#endif // _LIBCPP_WCTYPE_H
lib/libcxx/src/any.cpp+4
......@@ -14,6 +14,8 @@ const char* bad_any_cast::what() const noexcept { return "bad any cast"; }
1414
1515#include <__config>
1616
17#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 7
18
1719// Preserve std::experimental::any_bad_cast for ABI compatibility
1820// Even though it no longer exists in a header file
1921_LIBCPP_BEGIN_NAMESPACE_LFTS
......@@ -25,4 +27,6 @@ public:
2527
2628const char* bad_any_cast::what() const noexcept { return "bad any cast"; }
2729
30#endif
31
2832_LIBCPP_END_NAMESPACE_LFTS
lib/libcxx/src/atomic.cpp+365-80
......@@ -9,8 +9,13 @@
99#include <__thread/timed_backoff_policy.h>
1010#include <atomic>
1111#include <climits>
12#include <cstddef>
13#include <cstdint>
14#include <cstring>
1215#include <functional>
16#include <new>
1317#include <thread>
18#include <type_traits>
1419
1520#include "include/apple_availability.h"
1621
......@@ -41,6 +46,11 @@
4146// OpenBSD has no indirect syscalls
4247# define _LIBCPP_FUTEX(...) futex(__VA_ARGS__)
4348
49#elif defined(_WIN32)
50
51# include <memory>
52# include <windows.h>
53
4454#else // <- Add other operating systems here
4555
4656// Baseline needs no new headers
......@@ -49,17 +59,34 @@
4959
5060#endif
5161
62_LIBCPP_PUSH_MACROS
63#include <__undef_macros>
64
5265_LIBCPP_BEGIN_NAMESPACE_STD
5366
67struct NoTimeout {};
68
5469#ifdef __linux__
5570
56static void
57__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) {
58 static constexpr timespec __timeout = {2, 0};
59 _LIBCPP_FUTEX(__ptr, FUTEX_WAIT_PRIVATE, __val, &__timeout, 0, 0);
71template <std::size_t _Size, class MaybeTimeout>
72static void __platform_wait_on_address(void const* __ptr, void const* __val, MaybeTimeout maybe_timeout_ns) {
73 static_assert(_Size == 4, "Can only wait on 4 bytes value");
74 alignas(__cxx_contention_t) char buffer[_Size];
75 std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
76 static constexpr timespec __default_timeout = {2, 0};
77 timespec __timeout;
78 if constexpr (is_same_v<MaybeTimeout, NoTimeout>) {
79 __timeout = __default_timeout;
80 } else {
81 __timeout.tv_sec = maybe_timeout_ns / 1'000'000'000;
82 __timeout.tv_nsec = maybe_timeout_ns % 1'000'000'000;
83 }
84 _LIBCPP_FUTEX(__ptr, FUTEX_WAIT_PRIVATE, *reinterpret_cast<__cxx_contention_t const*>(&buffer), &__timeout, 0, 0);
6085}
6186
62static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, bool __notify_one) {
87template <std::size_t _Size>
88static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
89 static_assert(_Size == 4, "Can only wake up on 4 bytes value");
6390 _LIBCPP_FUTEX(__ptr, FUTEX_WAKE_PRIVATE, __notify_one ? 1 : INT_MAX, 0, 0, 0);
6491}
6592
......@@ -70,19 +97,41 @@ extern "C" int __ulock_wait(
7097extern "C" int __ulock_wake(uint32_t operation, void* addr, uint64_t wake_value);
7198
7299// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/ulock.h#L82
100# define UL_COMPARE_AND_WAIT 1
73101# define UL_COMPARE_AND_WAIT64 5
74102# define ULF_WAKE_ALL 0x00000100
75103
76static void
77__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) {
78 static_assert(sizeof(__cxx_atomic_contention_t) == 8, "Waiting on 8 bytes value");
79 __ulock_wait(UL_COMPARE_AND_WAIT64, const_cast<__cxx_atomic_contention_t*>(__ptr), __val, 0);
104template <std::size_t _Size, class MaybeTimeout>
105static void __platform_wait_on_address(void const* __ptr, void const* __val, MaybeTimeout maybe_timeout_ns) {
106 static_assert(_Size == 8 || _Size == 4, "Can only wait on 8 bytes or 4 bytes value");
107 auto __timeout_us = [&] {
108 if constexpr (is_same_v<MaybeTimeout, NoTimeout>) {
109 return uint32_t(0);
110 } else {
111 return std::max(static_cast<uint32_t>(maybe_timeout_ns / 1000), uint32_t(1));
112 }
113 }();
114 if constexpr (_Size == 4) {
115 alignas(uint32_t) char buffer[_Size];
116 std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
117 __ulock_wait(
118 UL_COMPARE_AND_WAIT, const_cast<void*>(__ptr), *reinterpret_cast<uint32_t const*>(&buffer), __timeout_us);
119 } else {
120 alignas(uint64_t) char buffer[_Size];
121 std::memcpy(&buffer, const_cast<const void*>(__val), _Size);
122 __ulock_wait(
123 UL_COMPARE_AND_WAIT64, const_cast<void*>(__ptr), *reinterpret_cast<uint64_t const*>(&buffer), __timeout_us);
124 }
80125}
81126
82static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, bool __notify_one) {
83 static_assert(sizeof(__cxx_atomic_contention_t) == 8, "Waking up on 8 bytes value");
84 __ulock_wake(
85 UL_COMPARE_AND_WAIT64 | (__notify_one ? 0 : ULF_WAKE_ALL), const_cast<__cxx_atomic_contention_t*>(__ptr), 0);
127template <std::size_t _Size>
128static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
129 static_assert(_Size == 8 || _Size == 4, "Can only wake up on 8 bytes or 4 bytes value");
130
131 if constexpr (_Size == 4)
132 __ulock_wake(UL_COMPARE_AND_WAIT | (__notify_one ? 0 : ULF_WAKE_ALL), const_cast<void*>(__ptr), 0);
133 else
134 __ulock_wake(UL_COMPARE_AND_WAIT64 | (__notify_one ? 0 : ULF_WAKE_ALL), const_cast<void*>(__ptr), 0);
86135}
87136
88137#elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
......@@ -92,119 +141,355 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo
92141 * limit its use to architectures where long and int64_t are synonyms.
93142 */
94143
95static void
96__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) {
97 _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr), UMTX_OP_WAIT, __val, nullptr, nullptr);
144template <std::size_t _Size, class MaybeTimeout>
145static void __platform_wait_on_address(void const* __ptr, void const* __val, MaybeTimeout maybe_timeout_ns) {
146 static_assert(_Size == 8, "Can only wait on 8 bytes value");
147 // At the moment, FreeBSD is stuck on stable ABI, which only supports platform wait with __cxx_contention_t
148 // It is safe to reinterpret_cast the val as it is ever going to be passed a __cxx_contention_t under this ABI
149 // If in the future FreeBSD decides to experiment unstable ABI to support more types, this cast will no longer be
150 // safe.
151 __cxx_contention_t value = *reinterpret_cast<const __cxx_contention_t*>(__val);
152 if constexpr (is_same_v<MaybeTimeout, NoTimeout>) {
153 _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, value, nullptr, nullptr);
154 } else {
155 timespec timeout{};
156 timeout.tv_sec = maybe_timeout_ns / 1'000'000'000;
157 timeout.tv_nsec = maybe_timeout_ns % 1'000'000'000;
158
159 _umtx_op(const_cast<void*>(__ptr),
160 UMTX_OP_WAIT,
161 value,
162 reinterpret_cast<void*>(static_cast<uintptr_t>(sizeof(timeout))),
163 &timeout);
164 }
165}
166
167template <std::size_t _Size>
168static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
169 static_assert(_Size == 8, "Can only wake up on 8 bytes value");
170 _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, nullptr, nullptr);
171}
172
173#elif defined(_WIN32)
174
175static void* win32_get_synch_api_function(const char* function_name) {
176 // Attempt to load the API set. Note that as per the Microsoft STL implementation, we assume this API is already
177 // loaded and accessible. While this isn't explicitly guaranteed by publicly available Win32 API documentation, it is
178 // true in practice, and may be guaranteed by internal documentation not released publicly. In any case the fact that
179 // the Microsoft STL made this assumption is reasonable basis to say that we can too. The alternative to this would be
180 // to use LoadLibrary, but then leak the module handle. We can't call FreeLibrary, as this would have to be triggered
181 // by a global static destructor, which would hang off DllMain, and calling FreeLibrary from DllMain is explicitly
182 // mentioned as not being allowed:
183 // https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain
184 // Given the range of bad options here, we have chosen to mirror what Microsoft did, as it seems fair to assume that
185 // Microsoft will guarantee compatibility for us, as we are exposed to the same conditions as all existing Windows
186 // apps using the Microsoft STL VS2015/2017/2019/2022 runtimes, where Windows 7 support has not been excluded at
187 // compile time.
188 static auto module_handle = GetModuleHandleW(L"api-ms-win-core-synch-l1-2-0.dll");
189 if (module_handle == nullptr) {
190 return nullptr;
191 }
192
193 // Attempt to locate the function in the API and return the result to the caller. Note that the NULL return from this
194 // method is documented as being interchangeable with nullptr.
195 // https://devblogs.microsoft.com/oldnewthing/20180307-00/?p=98175
196 return reinterpret_cast<void*>(GetProcAddress(module_handle, function_name));
98197}
99198
100static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, bool __notify_one) {
101 _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr), UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, nullptr, nullptr);
199template <std::size_t _Size, class MaybeTimeout>
200static void __platform_wait_on_address(void const* __ptr, void const* __val, MaybeTimeout maybe_timeout_ns) {
201 static_assert(_Size == 8, "Can only wait on 8 bytes value");
202 // WaitOnAddress was added in Windows 8 (build 9200)
203 static auto wait_on_address =
204 reinterpret_cast<BOOL(WINAPI*)(void*, PVOID, SIZE_T, DWORD)>(win32_get_synch_api_function("WaitOnAddress"));
205 if (wait_on_address != nullptr) {
206 auto timeout_ms = [&]() -> DWORD {
207 if constexpr (is_same_v<MaybeTimeout, NoTimeout>) {
208 return INFINITE;
209 } else {
210 uint64_t ms = maybe_timeout_ns / 1'000'000;
211 if (ms == 0 && maybe_timeout_ns > 100'000)
212 // Round up to 1ms if requested between 100us - 1ms
213 return 1;
214
215 return static_cast<DWORD>(std::min(static_cast<uint64_t>(INFINITE), ms));
216 }
217 }();
218 wait_on_address(const_cast<void*>(__ptr), const_cast<void*>(__val), _Size, timeout_ms);
219 } else {
220 std::chrono::nanoseconds timeout = std::chrono::nanoseconds(0);
221 if constexpr (!is_same_v<MaybeTimeout, NoTimeout>) {
222 timeout = std::chrono::nanoseconds(maybe_timeout_ns);
223 }
224 __libcpp_thread_poll_with_backoff(
225 [=]() -> bool { return std::memcmp(const_cast<const void*>(__ptr), __val, _Size) != 0; },
226 __libcpp_timed_backoff_policy(),
227 timeout);
228 }
229}
230
231template <std::size_t _Size>
232static void __platform_wake_by_address(void const* __ptr, bool __notify_one) {
233 static_assert(_Size == 8, "Can only wake up on 8 bytes value");
234 if (__notify_one) {
235 // WakeByAddressSingle was added in Windows 8 (build 9200)
236 static auto wake_by_address_single =
237 reinterpret_cast<void(WINAPI*)(PVOID)>(win32_get_synch_api_function("WakeByAddressSingle"));
238 if (wake_by_address_single != nullptr) {
239 wake_by_address_single(const_cast<void*>(__ptr));
240 } else {
241 // The fallback implementation of waking does nothing, as the fallback wait implementation just does polling, so
242 // there's nothing to do here.
243 }
244 } else {
245 // WakeByAddressAll was added in Windows 8 (build 9200)
246 static auto wake_by_address_all =
247 reinterpret_cast<void(WINAPI*)(PVOID)>(win32_get_synch_api_function("WakeByAddressAll"));
248 if (wake_by_address_all != nullptr) {
249 wake_by_address_all(const_cast<void*>(__ptr));
250 } else {
251 // The fallback implementation of waking does nothing, as the fallback wait implementation just does polling, so
252 // there's nothing to do here.
253 }
254 }
102255}
103256
104257#else // <- Add other operating systems here
105258
106259// Baseline is just a timed backoff
107260
108static void
109__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) {
261template <std::size_t _Size, class MaybeTimeout>
262static void __platform_wait_on_address(void const* __ptr, void const* __val, MaybeTimeout maybe_timeout_ns) {
263 std::chrono::nanoseconds timeout = std::chrono::nanoseconds(0);
264 if constexpr (!is_same_v<MaybeTimeout, NoTimeout>) {
265 timeout = std::chrono::nanoseconds(maybe_timeout_ns);
266 }
110267 __libcpp_thread_poll_with_backoff(
111 [=]() -> bool { return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__ptr, memory_order_relaxed), __val); },
112 __libcpp_timed_backoff_policy());
268 [=]() -> bool { return std::memcmp(const_cast<const void*>(__ptr), __val, _Size) != 0; },
269 __libcpp_timed_backoff_policy(),
270 timeout);
113271}
114272
115static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile*, bool) {}
273template <std::size_t _Size>
274static void __platform_wake_by_address(void const*, bool) {}
116275
117276#endif // __linux__
118277
119static constexpr size_t __libcpp_contention_table_size = (1 << 8); /* < there's no magic in this number */
120
121struct alignas(64) /* aim to avoid false sharing */ __libcpp_contention_table_entry {
122 __cxx_atomic_contention_t __contention_state;
123 __cxx_atomic_contention_t __platform_state;
124 inline constexpr __libcpp_contention_table_entry() : __contention_state(0), __platform_state(0) {}
125};
126
127static __libcpp_contention_table_entry __libcpp_contention_table[__libcpp_contention_table_size];
128
129static hash<void const volatile*> __libcpp_contention_hasher;
130
131static __libcpp_contention_table_entry* __libcpp_contention_state(void const volatile* p) {
132 return &__libcpp_contention_table[__libcpp_contention_hasher(p) & (__libcpp_contention_table_size - 1)];
133}
278// =============================
279// Local hidden helper functions
280// =============================
134281
135282/* Given an atomic to track contention and an atomic to actually wait on, which may be
136283 the same atomic, we try to detect contention to avoid spuriously calling the platform. */
137284
138static void __libcpp_contention_notify(__cxx_atomic_contention_t volatile* __contention_state,
139 __cxx_atomic_contention_t const volatile* __platform_state,
140 bool __notify_one) {
141 if (0 != __cxx_atomic_load(__contention_state, memory_order_seq_cst))
285template <std::size_t _Size>
286static void
287__contention_notify(__cxx_atomic_contention_t* __waiter_count, void const* __address_to_notify, bool __notify_one) {
288 if (0 != __cxx_atomic_load(__waiter_count, memory_order_seq_cst))
142289 // We only call 'wake' if we consumed a contention bit here.
143 __libcpp_platform_wake_by_address(__platform_state, __notify_one);
144}
145static __cxx_contention_t
146__libcpp_contention_monitor_for_wait(__cxx_atomic_contention_t volatile* /*__contention_state*/,
147 __cxx_atomic_contention_t const volatile* __platform_state) {
148 // We will monitor this value.
149 return __cxx_atomic_load(__platform_state, memory_order_acquire);
150}
151static void __libcpp_contention_wait(__cxx_atomic_contention_t volatile* __contention_state,
152 __cxx_atomic_contention_t const volatile* __platform_state,
153 __cxx_contention_t __old_value) {
154 __cxx_atomic_fetch_add(__contention_state, __cxx_contention_t(1), memory_order_relaxed);
155 // https://github.com/llvm/llvm-project/issues/109290
290 __platform_wake_by_address<_Size>(__address_to_notify, __notify_one);
291}
292
293template <std::size_t _Size, class MaybeTimeout>
294static void __contention_wait(__cxx_atomic_contention_t* __waiter_count,
295 void const* __address_to_wait,
296 void const* __old_value,
297 MaybeTimeout maybe_timeout_ns) {
298 __cxx_atomic_fetch_add(__waiter_count, __cxx_contention_t(1), memory_order_relaxed);
299 // https://llvm.org/PR109290
156300 // There are no platform guarantees of a memory barrier in the platform wait implementation
157301 __cxx_atomic_thread_fence(memory_order_seq_cst);
158302 // We sleep as long as the monitored value hasn't changed.
159 __libcpp_platform_wait_on_address(__platform_state, __old_value);
160 __cxx_atomic_fetch_sub(__contention_state, __cxx_contention_t(1), memory_order_release);
303 __platform_wait_on_address<_Size>(__address_to_wait, __old_value, maybe_timeout_ns);
304 __cxx_atomic_fetch_sub(__waiter_count, __cxx_contention_t(1), memory_order_release);
305}
306
307static constexpr size_t __contention_table_size = (1 << 8); /* < there's no magic in this number */
308
309static constexpr hash<void const*> __contention_hasher;
310
311// Waiter count table for all atomics with the correct size that use itself as the wait/notify address.
312
313struct alignas(
314 std::hardware_constructive_interference_size) /* aim to avoid false sharing */ __contention_state_native {
315 __cxx_atomic_contention_t __waiter_count;
316 constexpr __contention_state_native() : __waiter_count(0) {}
317};
318
319static __contention_state_native __contention_table_native[__contention_table_size];
320
321static __cxx_atomic_contention_t* __get_native_waiter_count(void const* p) {
322 return &__contention_table_native[__contention_hasher(p) & (__contention_table_size - 1)].__waiter_count;
323}
324
325// Global contention table for all atomics with the wrong size that use the global table's atomic as wait/notify
326// address.
327
328struct alignas(
329 std::hardware_constructive_interference_size) /* aim to avoid false sharing */ __contention_state_global {
330 __cxx_atomic_contention_t __waiter_count;
331 __cxx_atomic_contention_t __platform_state;
332 constexpr __contention_state_global() : __waiter_count(0), __platform_state(0) {}
333};
334
335static __contention_state_global __contention_table_global[__contention_table_size];
336
337static __contention_state_global* __get_global_contention_state(void const* p) {
338 return &__contention_table_global[__contention_hasher(p) & (__contention_table_size - 1)];
161339}
162340
163341/* When the incoming atomic is the wrong size for the platform wait size, need to
164342 launder the value sequence through an atomic from our table. */
165343
166static void __libcpp_atomic_notify(void const volatile* __location) {
167 auto const __entry = __libcpp_contention_state(__location);
344static void __atomic_notify_global_table(void const* __location) {
345 auto const __entry = __get_global_contention_state(__location);
168346 // The value sequence laundering happens on the next line below.
169347 __cxx_atomic_fetch_add(&__entry->__platform_state, __cxx_contention_t(1), memory_order_seq_cst);
170 __libcpp_contention_notify(
171 &__entry->__contention_state,
172 &__entry->__platform_state,
173 false /* when laundering, we can't handle notify_one */);
348 __contention_notify<sizeof(__cxx_atomic_contention_t)>(
349 &__entry->__waiter_count, &__entry->__platform_state, false /* when laundering, we can't handle notify_one */);
350}
351
352// =============================
353// New dylib exported symbols
354// =============================
355
356// global
357_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __atomic_monitor_global(void const* __location) noexcept {
358 auto const __entry = __get_global_contention_state(__location);
359 return __cxx_atomic_load(&__entry->__platform_state, memory_order_acquire);
360}
361
362_LIBCPP_EXPORTED_FROM_ABI void
363__atomic_wait_global_table(void const* __location, __cxx_contention_t __old_value) noexcept {
364 auto const __entry = __get_global_contention_state(__location);
365 __contention_wait<sizeof(__cxx_atomic_contention_t)>(
366 &__entry->__waiter_count, &__entry->__platform_state, &__old_value, NoTimeout{});
367}
368
369_LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_global_table_with_timeout(
370 void const* __location, __cxx_contention_t __old_value, uint64_t __timeout_ns) _NOEXCEPT {
371 auto const __entry = __get_global_contention_state(__location);
372 __contention_wait<sizeof(__cxx_atomic_contention_t)>(
373 &__entry->__waiter_count, &__entry->__platform_state, &__old_value, __timeout_ns);
374}
375
376_LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_global_table(void const* __location) noexcept {
377 __atomic_notify_global_table(__location);
378}
379
380_LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_global_table(void const* __location) noexcept {
381 __atomic_notify_global_table(__location);
382}
383
384// native
385
386template <std::size_t _Size>
387_LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_native(void const* __address, void const* __old_value) noexcept {
388 __contention_wait<_Size>(__get_native_waiter_count(__address), __address, __old_value, NoTimeout{});
174389}
390
391template <std::size_t _Size>
392_LIBCPP_EXPORTED_FROM_ABI void
393__atomic_wait_native_with_timeout(void const* __address, void const* __old_value, uint64_t __timeout_ns) noexcept {
394 __contention_wait<_Size>(__get_native_waiter_count(__address), __address, __old_value, __timeout_ns);
395}
396
397template <std::size_t _Size>
398_LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_native(void const* __location) noexcept {
399 __contention_notify<_Size>(__get_native_waiter_count(__location), __location, true);
400}
401
402template <std::size_t _Size>
403_LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native(void const* __location) noexcept {
404 __contention_notify<_Size>(__get_native_waiter_count(__location), __location, false);
405}
406
407// ==================================================
408// Instantiation of the templates with supported size
409// ==================================================
410
411#if defined(_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE)
412
413# define _INSTANTIATE(_SIZE) \
414 template _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_native<_SIZE>(void const*, void const*) noexcept; \
415 template _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_native_with_timeout<_SIZE>( \
416 void const*, void const*, uint64_t) noexcept; \
417 template _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_native<_SIZE>(void const*) noexcept; \
418 template _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native<_SIZE>(void const*) noexcept;
419
420_LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_INSTANTIATE)
421
422# undef _INSTANTIATE
423
424#else // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
425
426template _LIBCPP_EXPORTED_FROM_ABI void
427__atomic_wait_native<sizeof(__cxx_contention_t)>(void const* __address, void const* __old_value) noexcept;
428
429template _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_native_with_timeout<sizeof(__cxx_contention_t)>(
430 void const* __address, void const* __old_value, uint64_t) noexcept;
431
432template _LIBCPP_EXPORTED_FROM_ABI void
433__atomic_notify_one_native<sizeof(__cxx_contention_t)>(void const* __location) noexcept;
434
435template _LIBCPP_EXPORTED_FROM_ABI void
436__atomic_notify_all_native<sizeof(__cxx_contention_t)>(void const* __location) noexcept;
437
438#endif // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
439
440// =============================================================
441// Old dylib exported symbols, for backwards compatibility
442// =============================================================
443_LIBCPP_DIAGNOSTIC_PUSH
444_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-prototypes")
445
175446_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile* __location) noexcept {
176 __libcpp_atomic_notify(__location);
447 __atomic_notify_global_table(const_cast<void const*>(__location));
177448}
449
178450_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile* __location) noexcept {
179 __libcpp_atomic_notify(__location);
451 __atomic_notify_global_table(const_cast<void const*>(__location));
180452}
453
181454_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile* __location) noexcept {
182 auto const __entry = __libcpp_contention_state(__location);
183 return __libcpp_contention_monitor_for_wait(&__entry->__contention_state, &__entry->__platform_state);
455 auto const __entry = __get_global_contention_state(const_cast<void const*>(__location));
456 return __cxx_atomic_load(&__entry->__platform_state, memory_order_acquire);
184457}
458
185459_LIBCPP_EXPORTED_FROM_ABI void
186460__libcpp_atomic_wait(void const volatile* __location, __cxx_contention_t __old_value) noexcept {
187 auto const __entry = __libcpp_contention_state(__location);
188 __libcpp_contention_wait(&__entry->__contention_state, &__entry->__platform_state, __old_value);
461 auto const __entry = __get_global_contention_state(const_cast<void const*>(__location));
462 __contention_wait<sizeof(__cxx_atomic_contention_t)>(
463 &__entry->__waiter_count, &__entry->__platform_state, &__old_value, NoTimeout{});
189464}
190465
191/* When the incoming atomic happens to be the platform wait size, we still need to use the
192 table for the contention detection, but we can use the atomic directly for the wait. */
193
194466_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile* __location) noexcept {
195 __libcpp_contention_notify(&__libcpp_contention_state(__location)->__contention_state, __location, true);
467 auto __location_cast = const_cast<const void*>(static_cast<const volatile void*>(__location));
468 __contention_notify<sizeof(__cxx_atomic_contention_t)>(
469 __get_native_waiter_count(__location_cast), __location_cast, true);
196470}
471
197472_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile* __location) noexcept {
198 __libcpp_contention_notify(&__libcpp_contention_state(__location)->__contention_state, __location, false);
199}
200// This function is never used, but still exported for ABI compatibility.
201_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
202__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile* __location) noexcept {
203 return __libcpp_contention_monitor_for_wait(&__libcpp_contention_state(__location)->__contention_state, __location);
473 auto __location_cast = const_cast<const void*>(static_cast<const volatile void*>(__location));
474 __contention_notify<sizeof(__cxx_atomic_contention_t)>(
475 __get_native_waiter_count(__location_cast), __location_cast, false);
204476}
477
205478_LIBCPP_EXPORTED_FROM_ABI void
206479__libcpp_atomic_wait(__cxx_atomic_contention_t const volatile* __location, __cxx_contention_t __old_value) noexcept {
207 __libcpp_contention_wait(&__libcpp_contention_state(__location)->__contention_state, __location, __old_value);
480 auto __location_cast = const_cast<const void*>(static_cast<const volatile void*>(__location));
481 __contention_wait<sizeof(__cxx_atomic_contention_t)>(
482 __get_native_waiter_count(__location_cast), __location_cast, &__old_value, NoTimeout{});
208483}
209484
485// this function is even unused in the old ABI
486_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
487__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile* __location) noexcept {
488 return __cxx_atomic_load(__location, memory_order_acquire);
489}
490
491_LIBCPP_DIAGNOSTIC_POP
492
210493_LIBCPP_END_NAMESPACE_STD
494
495_LIBCPP_POP_MACROS
lib/libcxx/src/barrier.cpp+4-3
......@@ -60,11 +60,12 @@ public:
6060_LIBCPP_EXPORTED_FROM_ABI __barrier_algorithm_base* __construct_barrier_algorithm_base(ptrdiff_t& __expected) {
6161 return new __barrier_algorithm_base(__expected);
6262}
63_LIBCPP_EXPORTED_FROM_ABI bool
64__arrive_barrier_algorithm_base(__barrier_algorithm_base* __barrier, __barrier_phase_t __old_phase) noexcept {
63_LIBCPP_EXPORTED_FROM_ABI bool __arrive_barrier_algorithm_base(
64 _LIBCPP_NOESCAPE __barrier_algorithm_base* __barrier, __barrier_phase_t __old_phase) noexcept {
6565 return __barrier->__arrive(__old_phase);
6666}
67_LIBCPP_EXPORTED_FROM_ABI void __destroy_barrier_algorithm_base(__barrier_algorithm_base* __barrier) noexcept {
67_LIBCPP_EXPORTED_FROM_ABI void
68__destroy_barrier_algorithm_base(_LIBCPP_NOESCAPE __barrier_algorithm_base* __barrier) noexcept {
6869 delete __barrier;
6970}
7071
lib/libcxx/src/charconv.cpp+6-3
......@@ -14,17 +14,20 @@
1414
1515_LIBCPP_BEGIN_NAMESPACE_STD
1616
17#ifndef _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
17#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 15
1818
1919namespace __itoa {
2020
21_LIBCPP_DIAGNOSTIC_PUSH
22_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-prototypes")
23// These functions exist for ABI compatibility, so we don't ever want a declaration prior to the definition.
2124_LIBCPP_EXPORTED_FROM_ABI char* __u32toa(uint32_t value, char* buffer) noexcept { return __base_10_u32(buffer, value); }
22
2325_LIBCPP_EXPORTED_FROM_ABI char* __u64toa(uint64_t value, char* buffer) noexcept { return __base_10_u64(buffer, value); }
26_LIBCPP_DIAGNOSTIC_POP
2427
2528} // namespace __itoa
2629
27#endif // _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
30#endif // _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 15
2831
2932// The original version of floating-point to_chars was written by Microsoft and
3033// contributed with the following license.
lib/libcxx/src/condition_variable_destructor.cpp+1-1
......@@ -14,7 +14,7 @@
1414#include <__config>
1515#include <__thread/support.h>
1616
17#if _LIBCPP_ABI_VERSION == 1 || !_LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
17#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 9 || !_LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
1818# define NEEDS_CONDVAR_DESTRUCTOR
1919#endif
2020
lib/libcxx/src/error_category.cpp+3-1
......@@ -8,7 +8,9 @@
88
99#include <__config>
1010
11#ifdef _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS
11// This has technically been removed in LLVM 3.4
12#if !defined(_LIBCPP_OBJECT_FORMAT_COFF) && !defined(_LIBCPP_OBJECT_FORMAT_XCOFF) && \
13 _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 4
1214# define _LIBCPP_ERROR_CATEGORY_DEFINE_LEGACY_INLINE_FUNCTIONS
1315#endif
1416
lib/libcxx/src/exception.cpp+2-10
......@@ -9,20 +9,12 @@
99#define _LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION
1010#define _LIBCPP_DISABLE_DEPRECATION_WARNINGS
1111
12#include <exception>
13#include <new>
14#include <typeinfo>
15
16#if defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI)
17# include <cxxabi.h>
18using namespace __cxxabiv1;
19# define HAVE_DEPENDENT_EH_ABI 1
20#endif
12#include <__config>
2113
2214#if defined(_LIBCPP_ABI_MICROSOFT)
2315# include "support/runtime/exception_msvc.ipp"
2416# include "support/runtime/exception_pointer_msvc.ipp"
25#elif defined(_LIBCPPABI_VERSION)
17#elif defined(LIBCXX_BUILDING_LIBCXXABI)
2618# include "support/runtime/exception_libcxxabi.ipp"
2719# include "support/runtime/exception_pointer_cxxabi.ipp"
2820#elif defined(LIBCXXRT)
lib/libcxx/src/experimental/time_zone.cpp+1-1
......@@ -720,7 +720,7 @@ __get_sys_info(sys_seconds __time,
720720// Iff the "offsets" are the same '__current.__end' is replaced with
721721// '__next.__end', which effectively merges the two objects in one object. The
722722// function returns true if a merge occurred.
723[[nodiscard]] bool __merge_continuation(sys_info& __current, const sys_info& __next) {
723[[nodiscard]] static bool __merge_continuation(sys_info& __current, const sys_info& __next) {
724724 if (__current.end != __next.begin)
725725 return false;
726726
lib/libcxx/src/experimental/tzdb.cpp+4-1
......@@ -49,6 +49,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
4949
5050namespace chrono {
5151
52_LIBCPP_DIAGNOSTIC_PUSH
53_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-prototypes")
5254// This function is weak so it can be overriden in the tests. The
5355// declaration is in the test header test/support/test_tzdb.h
5456_LIBCPP_WEAK string_view __libcpp_tzdb_directory() {
......@@ -59,6 +61,7 @@ _LIBCPP_WEAK string_view __libcpp_tzdb_directory() {
5961 abort();
6062#endif
6163}
64_LIBCPP_DIAGNOSTIC_POP
6265
6366//===----------------------------------------------------------------------===//
6467// Details
......@@ -767,7 +770,7 @@ void __init_tzdb(tzdb& __tzdb, __tz::__rules_storage_type& __rules) {
767770 // On Linux systems it seems /etc/timezone is deprecated and being phased out.
768771 // This file is used when /etc/localtime does not exist, or when it exists but
769772 // is not a symlink. For more information and links see
770 // https://github.com/llvm/llvm-project/issues/105634
773 // https://llvm.org/PR105634
771774
772775 string __name = chrono::__current_zone_environment();
773776
lib/libcxx/src/filesystem/error.h+4-22
......@@ -128,17 +128,8 @@ struct ErrorHandler {
128128 T report(const error_code& ec, const char* msg, ...) const {
129129 va_list ap;
130130 va_start(ap, msg);
131#if _LIBCPP_HAS_EXCEPTIONS
132 try {
133#endif // _LIBCPP_HAS_EXCEPTIONS
134 report_impl(ec, msg, ap);
135#if _LIBCPP_HAS_EXCEPTIONS
136 } catch (...) {
137 va_end(ap);
138 throw;
139 }
140#endif // _LIBCPP_HAS_EXCEPTIONS
141 va_end(ap);
131 __scope_guard guard([&] { va_end(ap); });
132 report_impl(ec, msg, ap);
142133 return error_value<T>();
143134 }
144135
......@@ -148,17 +139,8 @@ struct ErrorHandler {
148139 T report(errc const& err, const char* msg, ...) const {
149140 va_list ap;
150141 va_start(ap, msg);
151#if _LIBCPP_HAS_EXCEPTIONS
152 try {
153#endif // _LIBCPP_HAS_EXCEPTIONS
154 report_impl(make_error_code(err), msg, ap);
155#if _LIBCPP_HAS_EXCEPTIONS
156 } catch (...) {
157 va_end(ap);
158 throw;
159 }
160#endif // _LIBCPP_HAS_EXCEPTIONS
161 va_end(ap);
142 __scope_guard guard([&] { va_end(ap); });
143 report_impl(make_error_code(err), msg, ap);
162144 return error_value<T>();
163145 }
164146
lib/libcxx/src/filesystem/format_string.h+9-18
......@@ -11,6 +11,7 @@
1111
1212#include <__assert>
1313#include <__config>
14#include <__utility/scope_guard.h>
1415#include <array>
1516#include <cstdarg>
1617#include <cstddef>
......@@ -34,20 +35,19 @@ inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string vformat_string(const ch
3435
3536 va_list apcopy;
3637 va_copy(apcopy, ap);
37 int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);
38 int size = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);
3839 va_end(apcopy);
3940
4041 string result;
41 if (static_cast<size_t>(ret) < buf.size()) {
42 result.assign(buf.data(), static_cast<size_t>(ret));
42 if (static_cast<size_t>(size) < buf.size()) {
43 result.assign(buf.data(), static_cast<size_t>(size));
4344 } else {
4445 // we did not provide a long enough buffer on our first attempt. The
4546 // return value is the number of bytes (excluding the null byte) that are
4647 // needed for formatting.
47 size_t size_with_null = static_cast<size_t>(ret) + 1;
48 result.__resize_default_init(size_with_null - 1);
49 ret = ::vsnprintf(&result[0], size_with_null, msg, ap);
50 _LIBCPP_ASSERT_INTERNAL(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
48 result.resize_and_overwrite(size, [&](char* res, size_t n) { return ::vsnprintf(res, n, msg, ap); });
49 _LIBCPP_ASSERT_INTERNAL(static_cast<size_t>(size) == result.size(),
50 "vsnprintf did not result in the same number of characters as the first attempt?");
5151 }
5252 return result;
5353}
......@@ -56,17 +56,8 @@ inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string format_string(const cha
5656 string ret;
5757 va_list ap;
5858 va_start(ap, msg);
59#if _LIBCPP_HAS_EXCEPTIONS
60 try {
61#endif // _LIBCPP_HAS_EXCEPTIONS
62 ret = detail::vformat_string(msg, ap);
63#if _LIBCPP_HAS_EXCEPTIONS
64 } catch (...) {
65 va_end(ap);
66 throw;
67 }
68#endif // _LIBCPP_HAS_EXCEPTIONS
69 va_end(ap);
59 __scope_guard guard([&] { va_end(ap); });
60 ret = detail::vformat_string(msg, ap);
7061 return ret;
7162}
7263
lib/libcxx/src/filesystem/int128_builtins.cpp+2
......@@ -16,6 +16,8 @@
1616#include <__config>
1717#include <climits>
1818
19_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-prototypes") // See the FIXME above
20
1921#if _LIBCPP_HAS_INT128
2022
2123extern "C" __attribute__((no_sanitize("undefined"))) _LIBCPP_EXPORTED_FROM_ABI __int128_t
lib/libcxx/src/filesystem/operations.cpp+2-9
......@@ -41,17 +41,10 @@
4141#include <time.h>
4242
4343// since Linux 4.5 and FreeBSD 13, but the Linux libc wrapper is only provided by glibc >= 2.27 and musl
44#if defined(__linux__)
45# if defined(_LIBCPP_GLIBC_PREREQ)
46# if _LIBCPP_GLIBC_PREREQ(2, 27)
47# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE
48# endif
49# elif _LIBCPP_HAS_MUSL_LIBC
50# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE
51# endif
52#elif defined(__FreeBSD__)
44#if _LIBCPP_GLIBC_PREREQ(2, 27) || _LIBCPP_HAS_MUSL_LIBC || defined(__FreeBSD__)
5345# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE
5446#endif
47
5548#if __has_include(<sys/sendfile.h>)
5649# include <sys/sendfile.h>
5750# define _LIBCPP_FILESYSTEM_USE_SENDFILE
lib/libcxx/src/filesystem/path.cpp+3-1
......@@ -292,7 +292,9 @@ path path::lexically_relative(const path& base) const {
292292 // return a path constructed with 'n' dot-dot elements, followed by the
293293 // elements of '*this' after the mismatch.
294294 path Result;
295 // FIXME: Reserve enough room in Result that it won't have to re-allocate.
295 constexpr size_t ElemSize = 2; // ".."
296 constexpr size_t SeparatorSize = 1; // separator is always a single char
297 Result.__reserve(ElemCount * (ElemSize + SeparatorSize) + SeparatorSize + PP.Path.size());
296298 while (ElemCount--)
297299 Result /= PATHSTR("..");
298300 for (; PP; ++PP)
lib/libcxx/src/include/aligned_alloc.h created+65
......@@ -0,0 +1,65 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP_SRC_ALIGNED_ALLOC_H
10#define _LIBCPP_SRC_ALIGNED_ALLOC_H
11
12#include <__config>
13#include <cstdlib>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_BEGIN_NAMESPACE_STD
20
21#if _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION
22
23// Low-level helpers to call the aligned allocation and deallocation functions
24// on the target platform. This is used to implement libc++'s own memory
25// allocation routines -- if you need to allocate memory inside the library,
26// chances are that you want to use `__libcpp_allocate` instead.
27//
28// Returns the allocated memory, or `nullptr` on failure.
29inline _LIBCPP_HIDE_FROM_ABI void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
30# if defined(_LIBCPP_MSVCRT_LIKE)
31 return ::_aligned_malloc(__size, __alignment);
32
33// Android only provides aligned_alloc when targeting API 28 or higher.
34# elif !defined(__ANDROID__) || __ANDROID_API__ >= 28
35 // aligned_alloc() requires that __size is a multiple of __alignment,
36 // but for C++ [new.delete.general], only states "if the value of an
37 // alignment argument passed to any of these functions is not a valid
38 // alignment value, the behavior is undefined".
39 // To handle calls such as ::operator new(1, std::align_val_t(128)), we
40 // round __size up to the next multiple of __alignment.
41 size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
42 // Rounding up could have wrapped around to zero, so we have to add another
43 // max() ternary to the actual call site to avoid succeeded in that case.
44 return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
45# else
46 void* __result = nullptr;
47 (void)::posix_memalign(&__result, __alignment, __size);
48 // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
49 return __result;
50# endif
51}
52
53inline _LIBCPP_HIDE_FROM_ABI void __libcpp_aligned_free(void* __ptr) {
54# if defined(_LIBCPP_MSVCRT_LIKE)
55 ::_aligned_free(__ptr);
56# else
57 ::free(__ptr);
58# endif
59}
60
61#endif // _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION
62
63_LIBCPP_END_NAMESPACE_STD
64
65#endif // _LIBCPP_SRC_ALIGNED_ALLOC_H
lib/libcxx/src/include/config_elast.h+1-1
......@@ -23,7 +23,7 @@
2323# define _LIBCPP_ELAST ELAST
2424#elif defined(__LLVM_LIBC__)
2525// No _LIBCPP_ELAST needed for LLVM libc
26#elif defined(_NEWLIB_VERSION)
26#elif _LIBCPP_LIBC_NEWLIB
2727# define _LIBCPP_ELAST __ELASTERROR
2828#elif defined(__NuttX__)
2929// No _LIBCPP_ELAST needed on NuttX
lib/libcxx/src/include/from_chars_floating_point.h+11-7
......@@ -9,11 +9,6 @@
99#ifndef _LIBCPP_SRC_INCLUDE_FROM_CHARS_FLOATING_POINT_H
1010#define _LIBCPP_SRC_INCLUDE_FROM_CHARS_FLOATING_POINT_H
1111
12// These headers are in the shared LLVM-libc header library.
13#include "shared/fp_bits.h"
14#include "shared/str_to_float.h"
15#include "shared/str_to_integer.h"
16
1712#include <__assert>
1813#include <__config>
1914#include <cctype>
......@@ -21,6 +16,15 @@
2116#include <concepts>
2217#include <limits>
2318
19// Make sure we use libc++'s assertion machinery within the shared code we use
20// from LLVM libc.
21#define LIBC_ASSERT(cond) _LIBCPP_ASSERT((cond), _LIBCPP_TOSTRING(cond))
22
23// These headers are in the shared LLVM-libc header library.
24#include "shared/fp_bits.h"
25#include "shared/str_to_float.h"
26#include "shared/str_to_integer.h"
27
2428// Included for the _Floating_type_traits class
2529#include "to_chars_floating_point.h"
2630
......@@ -193,7 +197,7 @@ struct __exponent_result {
193197// __offset, 0, false. This allows using the results unconditionally, the
194198// __present is important for the scientific notation, where the value is
195199// mandatory.
196__exponent_result __parse_exponent(const char* __input, size_t __n, size_t __offset, char __marker) {
200static __exponent_result __parse_exponent(const char* __input, size_t __n, size_t __offset, char __marker) {
197201 if (__offset + 1 < __n && // an exponent always needs at least one digit.
198202 std::tolower(__input[__offset]) == __marker && //
199203 !std::isspace(__input[__offset + 1]) // leading whitespace is not allowed.
......@@ -213,7 +217,7 @@ __exponent_result __parse_exponent(const char* __input, size_t __n, size_t __off
213217}
214218
215219// Here we do this operation as int64 to avoid overflow.
216int32_t __merge_exponents(int64_t __fractional, int64_t __exponent, int __max_biased_exponent) {
220static int32_t __merge_exponents(int64_t __fractional, int64_t __exponent, int __max_biased_exponent) {
217221 int64_t __sum = __fractional + __exponent;
218222
219223 if (__sum > __max_biased_exponent)
lib/libcxx/src/include/overridable_function.h+8-10
......@@ -29,12 +29,12 @@
2929// This is a low-level utility which does not work on all platforms, since it needs
3030// to make assumptions about the object file format in use. Furthermore, it requires
3131// the "base definition" of the function (the one we want to check whether it has been
32// overridden) to be defined using the _LIBCPP_OVERRIDABLE_FUNCTION macro.
32// overridden) to be defined using the OVERRIDABLE_FUNCTION macro.
3333//
3434// This currently works with Mach-O files (used on Darwin) and with ELF files (used on Linux
3535// and others). On platforms where we know how to implement this detection, the macro
3636// _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION is defined to 1, and it is defined to 0 on
37// other platforms. The _LIBCPP_OVERRIDABLE_FUNCTION macro is defined to perform a normal
37// other platforms. The OVERRIDABLE_FUNCTION macro is defined to perform a normal
3838// function definition on unsupported platforms so that it can be used to define functions
3939// regardless of whether detection is actually supported.
4040//
......@@ -44,7 +44,7 @@
4444// Let's say we want to check whether a weak function `f` has been overridden by the user.
4545// The general mechanism works by placing `f`'s definition (in the libc++ built library)
4646// inside a special section, which we do using the `__section__` attribute via the
47// _LIBCPP_OVERRIDABLE_FUNCTION macro.
47// OVERRIDABLE_FUNCTION macro.
4848//
4949// Then, when comes the time to check whether the function has been overridden, we take
5050// the address of the function and we check whether it falls inside the special function
......@@ -66,11 +66,10 @@
6666#if defined(_LIBCPP_OBJECT_FORMAT_MACHO)
6767
6868# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
69# define _LIBCPP_OVERRIDABLE_FUNCTION(type, name, arglist) \
70 __attribute__((__section__("__TEXT,__lcxx_override,regular,pure_instructions"))) _LIBCPP_WEAK type name arglist
69# define OVERRIDABLE_FUNCTION \
70 __attribute__((__section__("__TEXT,__lcxx_override,regular,pure_instructions"))) _LIBCPP_WEAK
7171
72_LIBCPP_BEGIN_NAMESPACE_STD
73template <typename T, T* _Func>
72_LIBCPP_BEGIN_NAMESPACE_STD template <typename T, T* _Func>
7473_LIBCPP_HIDE_FROM_ABI inline bool __is_function_overridden() noexcept {
7574 // Declare two dummy bytes and give them these special `__asm` values. These values are
7675 // defined by the linker, which means that referring to `&__lcxx_override_start` will
......@@ -100,8 +99,7 @@ _LIBCPP_END_NAMESPACE_STD
10099#elif defined(_LIBCPP_OBJECT_FORMAT_ELF) && !defined(__NVPTX__)
101100
102101# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
103# define _LIBCPP_OVERRIDABLE_FUNCTION(type, name, arglist) \
104 __attribute__((__section__("__lcxx_override"))) _LIBCPP_WEAK type name arglist
102# define OVERRIDABLE_FUNCTION __attribute__((__section__("__lcxx_override"))) _LIBCPP_WEAK
105103
106104// This is very similar to what we do for Mach-O above. The ELF linker will implicitly define
107105// variables with those names corresponding to the start and the end of the section.
......@@ -129,7 +127,7 @@ _LIBCPP_END_NAMESPACE_STD
129127#else
130128
131129# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 0
132# define _LIBCPP_OVERRIDABLE_FUNCTION(type, name, arglist) _LIBCPP_WEAK type name arglist
130# define OVERRIDABLE_FUNCTION _LIBCPP_WEAK
133131
134132#endif
135133
lib/libcxx/src/iostream.cpp+56-37
......@@ -16,24 +16,40 @@
1616
1717_LIBCPP_BEGIN_NAMESPACE_STD
1818
19// This file implements the various stream objects provided inside <iostream>. We're doing some ODR violations in here,
20// so this quite fragile. Specifically, the size of the stream objects (i.e. cout, cin etc.) needs to stay the same.
21// For that reason, we have `stream` and `stream_data` separated into two objects. The public `stream` objects only
22// contain the actual stream, while the private `stream_data` objects contains the `basic_streambuf` we're using as well
23// as the mbstate_t. `stream_data` objects are only accessible within the library, so they aren't ABI sensitive and we
24// can change them as we want.
25
26template <class StreamT>
27union stream {
28 constexpr stream() {}
29 stream(const stream&) = delete;
30 stream& operator=(const stream&) = delete;
31 constexpr ~stream() {}
32
33 StreamT value;
34};
35
1936template <class StreamT, class BufferT>
2037union stream_data {
2138 constexpr stream_data() {}
2239 constexpr ~stream_data() {}
2340 struct {
24 // The stream has to be the first element, since that's referenced by the stream declarations in <iostream>
25 StreamT stream;
2641 BufferT buffer;
2742 mbstate_t mb;
2843 };
29
30 void init(FILE* stdstream) {
31 mb = {};
32 std::construct_at(&buffer, stdstream, &mb);
33 std::construct_at(&stream, &buffer);
34 }
3544};
3645
46template <class StreamT, class BufferT>
47void init_stream(FILE* stdstream, stream<StreamT>& stream, stream_data<StreamT, BufferT>& data) {
48 data.mb = {};
49 std::construct_at(&data.buffer, stdstream, &data.mb);
50 std::construct_at(&stream.value, &data.buffer);
51}
52
3753#define CHAR_MANGLING_char "D"
3854#define CHAR_MANGLING_wchar_t "_W"
3955#define CHAR_MANGLING(CharT) CHAR_MANGLING_##CharT
......@@ -46,25 +62,28 @@ union stream_data {
4662
4763#ifdef _LIBCPP_ABI_MICROSOFT
4864# define STREAM(StreamT, BufferT, CharT, var) \
49 STRING_DATA_CONSTINIT stream_data<StreamT<CharT>, BufferT<CharT>> var __asm__( \
65 STRING_DATA_CONSTINIT stream_data<StreamT<CharT>, BufferT<CharT>> var##_data; \
66 _LIBCPP_EXPORTED_FROM_ABI STRING_DATA_CONSTINIT stream<StreamT<CharT>> var __asm__( \
5067 "?" #var "@" ABI_NAMESPACE_STR "@std@@3V?$" #StreamT \
5168 "@" CHAR_MANGLING(CharT) "U?$char_traits@" CHAR_MANGLING(CharT) "@" ABI_NAMESPACE_STR "@std@@@12@A")
5269#else
53# define STREAM(StreamT, BufferT, CharT, var) STRING_DATA_CONSTINIT stream_data<StreamT<CharT>, BufferT<CharT>> var
70# define STREAM(StreamT, BufferT, CharT, var) \
71 STRING_DATA_CONSTINIT stream_data<StreamT<CharT>, BufferT<CharT>> var##_data; \
72 _LIBCPP_EXPORTED_FROM_ABI STRING_DATA_CONSTINIT stream<StreamT<CharT>> var
5473#endif
5574
5675// These definitions and the declarations in <iostream> technically cause ODR violations, since they have different
5776// types (stream_data and {i,o}stream respectively). This means that <iostream> should never be included in this TU.
5877
59_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_istream, __stdinbuf, char, cin);
60_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, char, cout);
61_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, char, cerr);
62_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, char, clog);
78STREAM(basic_istream, __stdinbuf, char, cin);
79STREAM(basic_ostream, __stdoutbuf, char, cout);
80STREAM(basic_ostream, __stdoutbuf, char, cerr);
81STREAM(basic_ostream, __stdoutbuf, char, clog);
6382#if _LIBCPP_HAS_WIDE_CHARACTERS
64_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_istream, __stdinbuf, wchar_t, wcin);
65_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, wchar_t, wcout);
66_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, wchar_t, wcerr);
67_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, wchar_t, wclog);
83STREAM(basic_istream, __stdinbuf, wchar_t, wcin);
84STREAM(basic_ostream, __stdoutbuf, wchar_t, wcout);
85STREAM(basic_ostream, __stdoutbuf, wchar_t, wcerr);
86STREAM(basic_ostream, __stdoutbuf, wchar_t, wclog);
6887#endif // _LIBCPP_HAS_WIDE_CHARACTERS
6988
7089// Pretend we're inside a system header so the compiler doesn't flag the use of the init_priority
......@@ -98,34 +117,34 @@ public:
98117DoIOSInit::DoIOSInit() {
99118 force_locale_initialization();
100119
101 cin.init(stdin);
102 cout.init(stdout);
103 cerr.init(stderr);
104 clog.init(stderr);
120 init_stream(stdin, cin, cin_data);
121 init_stream(stdout, cout, cout_data);
122 init_stream(stderr, cerr, cerr_data);
123 init_stream(stderr, clog, clog_data);
105124
106 cin.stream.tie(&cout.stream);
107 std::unitbuf(cerr.stream);
108 cerr.stream.tie(&cout.stream);
125 cin.value.tie(&cout.value);
126 std::unitbuf(cerr.value);
127 cerr.value.tie(&cout.value);
109128
110129#if _LIBCPP_HAS_WIDE_CHARACTERS
111 wcin.init(stdin);
112 wcout.init(stdout);
113 wcerr.init(stderr);
114 wclog.init(stderr);
115
116 wcin.stream.tie(&wcout.stream);
117 std::unitbuf(wcerr.stream);
118 wcerr.stream.tie(&wcout.stream);
130 init_stream(stdin, wcin, wcin_data);
131 init_stream(stdout, wcout, wcout_data);
132 init_stream(stderr, wcerr, wcerr_data);
133 init_stream(stderr, wclog, wclog_data);
134
135 wcin.value.tie(&wcout.value);
136 std::unitbuf(wcerr.value);
137 wcerr.value.tie(&wcout.value);
119138#endif
120139}
121140
122141DoIOSInit::~DoIOSInit() {
123 cout.stream.flush();
124 clog.stream.flush();
142 cout.value.flush();
143 clog.value.flush();
125144
126145#if _LIBCPP_HAS_WIDE_CHARACTERS
127 wcout.stream.flush();
128 wclog.stream.flush();
146 wcout.value.flush();
147 wclog.value.flush();
129148#endif
130149}
131150
lib/libcxx/src/locale.cpp+213-196
......@@ -60,9 +60,8 @@ struct __libcpp_unique_locale {
6060
6161 __locale::__locale_t __loc_;
6262
63private:
64 __libcpp_unique_locale(__libcpp_unique_locale const&);
65 __libcpp_unique_locale& operator=(__libcpp_unique_locale const&);
63 __libcpp_unique_locale(__libcpp_unique_locale const&) = delete;
64 __libcpp_unique_locale& operator=(__libcpp_unique_locale const&) = delete;
6665};
6766
6867#ifdef __cloc_defined
......@@ -88,16 +87,6 @@ T& make(Args... args) {
8887 return *obj;
8988}
9089
91template <typename T, size_t N>
92inline constexpr size_t countof(const T (&)[N]) {
93 return N;
94}
95
96template <typename T>
97inline constexpr size_t countof(const T* const begin, const T* const end) {
98 return static_cast<size_t>(end - begin);
99}
100
10190string build_name(const string& other, const string& one, locale::category c) {
10291 if (other == "*" || one == "*")
10392 return "*";
......@@ -215,63 +204,58 @@ locale::__imp::__imp(size_t refs) : facet(refs), facets_(N), name_("C") {
215204}
216205
217206locale::__imp::__imp(const string& name, size_t refs) : facet(refs), facets_(N), name_(name) {
218#if _LIBCPP_HAS_EXCEPTIONS
219 try {
220#endif // _LIBCPP_HAS_EXCEPTIONS
221 facets_ = locale::classic().__locale_->facets_;
207 __exception_guard guard([&] {
222208 for (unsigned i = 0; i < facets_.size(); ++i)
223209 if (facets_[i])
224 facets_[i]->__add_shared();
225 install(new collate_byname<char>(name_));
210 facets_[i]->__release_shared();
211 });
212 facets_ = locale::classic().__locale_->facets_;
213 for (unsigned i = 0; i < facets_.size(); ++i)
214 if (facets_[i])
215 facets_[i]->__add_shared();
216 install(new collate_byname<char>(name_));
226217#if _LIBCPP_HAS_WIDE_CHARACTERS
227 install(new collate_byname<wchar_t>(name_));
218 install(new collate_byname<wchar_t>(name_));
228219#endif
229 install(new ctype_byname<char>(name_));
220 install(new ctype_byname<char>(name_));
230221#if _LIBCPP_HAS_WIDE_CHARACTERS
231 install(new ctype_byname<wchar_t>(name_));
222 install(new ctype_byname<wchar_t>(name_));
232223#endif
233 install(new codecvt_byname<char, char, mbstate_t>(name_));
224 install(new codecvt_byname<char, char, mbstate_t>(name_));
234225#if _LIBCPP_HAS_WIDE_CHARACTERS
235 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
226 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
236227#endif
237 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
238 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
239 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
240 _LIBCPP_SUPPRESS_DEPRECATED_POP
228 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
229 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
230 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
231 _LIBCPP_SUPPRESS_DEPRECATED_POP
241232#if _LIBCPP_HAS_CHAR8_T
242 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name_));
243 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name_));
233 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name_));
234 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name_));
244235#endif
245 install(new numpunct_byname<char>(name_));
236 install(new numpunct_byname<char>(name_));
246237#if _LIBCPP_HAS_WIDE_CHARACTERS
247 install(new numpunct_byname<wchar_t>(name_));
238 install(new numpunct_byname<wchar_t>(name_));
248239#endif
249 install(new moneypunct_byname<char, false>(name_));
250 install(new moneypunct_byname<char, true>(name_));
240 install(new moneypunct_byname<char, false>(name_));
241 install(new moneypunct_byname<char, true>(name_));
251242#if _LIBCPP_HAS_WIDE_CHARACTERS
252 install(new moneypunct_byname<wchar_t, false>(name_));
253 install(new moneypunct_byname<wchar_t, true>(name_));
243 install(new moneypunct_byname<wchar_t, false>(name_));
244 install(new moneypunct_byname<wchar_t, true>(name_));
254245#endif
255 install(new time_get_byname<char>(name_));
246 install(new time_get_byname<char>(name_));
256247#if _LIBCPP_HAS_WIDE_CHARACTERS
257 install(new time_get_byname<wchar_t>(name_));
248 install(new time_get_byname<wchar_t>(name_));
258249#endif
259 install(new time_put_byname<char>(name_));
250 install(new time_put_byname<char>(name_));
260251#if _LIBCPP_HAS_WIDE_CHARACTERS
261 install(new time_put_byname<wchar_t>(name_));
252 install(new time_put_byname<wchar_t>(name_));
262253#endif
263 install(new messages_byname<char>(name_));
254 install(new messages_byname<char>(name_));
264255#if _LIBCPP_HAS_WIDE_CHARACTERS
265 install(new messages_byname<wchar_t>(name_));
256 install(new messages_byname<wchar_t>(name_));
266257#endif
267#if _LIBCPP_HAS_EXCEPTIONS
268 } catch (...) {
269 for (unsigned i = 0; i < facets_.size(); ++i)
270 if (facets_[i])
271 facets_[i]->__release_shared();
272 throw;
273 }
274#endif // _LIBCPP_HAS_EXCEPTIONS
258 guard.__complete();
275259}
276260
277261locale::__imp::__imp(const __imp& other) : facets_(max<size_t>(N, other.facets_.size())), name_(other.name_) {
......@@ -287,71 +271,66 @@ locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
287271 for (unsigned i = 0; i < facets_.size(); ++i)
288272 if (facets_[i])
289273 facets_[i]->__add_shared();
290#if _LIBCPP_HAS_EXCEPTIONS
291 try {
292#endif // _LIBCPP_HAS_EXCEPTIONS
293 if (c & locale::collate) {
294 install(new collate_byname<char>(name));
274 __exception_guard guard([&] {
275 for (unsigned i = 0; i < facets_.size(); ++i)
276 if (facets_[i])
277 facets_[i]->__release_shared();
278 });
279 if (c & locale::collate) {
280 install(new collate_byname<char>(name));
295281#if _LIBCPP_HAS_WIDE_CHARACTERS
296 install(new collate_byname<wchar_t>(name));
282 install(new collate_byname<wchar_t>(name));
297283#endif
298 }
299 if (c & locale::ctype) {
300 install(new ctype_byname<char>(name));
284 }
285 if (c & locale::ctype) {
286 install(new ctype_byname<char>(name));
301287#if _LIBCPP_HAS_WIDE_CHARACTERS
302 install(new ctype_byname<wchar_t>(name));
288 install(new ctype_byname<wchar_t>(name));
303289#endif
304 install(new codecvt_byname<char, char, mbstate_t>(name));
290 install(new codecvt_byname<char, char, mbstate_t>(name));
305291#if _LIBCPP_HAS_WIDE_CHARACTERS
306 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
292 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
307293#endif
308 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
309 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
310 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
311 _LIBCPP_SUPPRESS_DEPRECATED_POP
294 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
295 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
296 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
297 _LIBCPP_SUPPRESS_DEPRECATED_POP
312298#if _LIBCPP_HAS_CHAR8_T
313 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name));
314 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name));
299 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name));
300 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name));
315301#endif
316 }
317 if (c & locale::monetary) {
318 install(new moneypunct_byname<char, false>(name));
319 install(new moneypunct_byname<char, true>(name));
302 }
303 if (c & locale::monetary) {
304 install(new moneypunct_byname<char, false>(name));
305 install(new moneypunct_byname<char, true>(name));
320306#if _LIBCPP_HAS_WIDE_CHARACTERS
321 install(new moneypunct_byname<wchar_t, false>(name));
322 install(new moneypunct_byname<wchar_t, true>(name));
307 install(new moneypunct_byname<wchar_t, false>(name));
308 install(new moneypunct_byname<wchar_t, true>(name));
323309#endif
324 }
325 if (c & locale::numeric) {
326 install(new numpunct_byname<char>(name));
310 }
311 if (c & locale::numeric) {
312 install(new numpunct_byname<char>(name));
327313#if _LIBCPP_HAS_WIDE_CHARACTERS
328 install(new numpunct_byname<wchar_t>(name));
314 install(new numpunct_byname<wchar_t>(name));
329315#endif
330 }
331 if (c & locale::time) {
332 install(new time_get_byname<char>(name));
316 }
317 if (c & locale::time) {
318 install(new time_get_byname<char>(name));
333319#if _LIBCPP_HAS_WIDE_CHARACTERS
334 install(new time_get_byname<wchar_t>(name));
320 install(new time_get_byname<wchar_t>(name));
335321#endif
336 install(new time_put_byname<char>(name));
322 install(new time_put_byname<char>(name));
337323#if _LIBCPP_HAS_WIDE_CHARACTERS
338 install(new time_put_byname<wchar_t>(name));
324 install(new time_put_byname<wchar_t>(name));
339325#endif
340 }
341 if (c & locale::messages) {
342 install(new messages_byname<char>(name));
326 }
327 if (c & locale::messages) {
328 install(new messages_byname<char>(name));
343329#if _LIBCPP_HAS_WIDE_CHARACTERS
344 install(new messages_byname<wchar_t>(name));
330 install(new messages_byname<wchar_t>(name));
345331#endif
346 }
347#if _LIBCPP_HAS_EXCEPTIONS
348 } catch (...) {
349 for (unsigned i = 0; i < facets_.size(); ++i)
350 if (facets_[i])
351 facets_[i]->__release_shared();
352 throw;
353332 }
354#endif // _LIBCPP_HAS_EXCEPTIONS
333 guard.__complete();
355334}
356335
357336template <class F>
......@@ -366,87 +345,83 @@ locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
366345 for (unsigned i = 0; i < facets_.size(); ++i)
367346 if (facets_[i])
368347 facets_[i]->__add_shared();
369#if _LIBCPP_HAS_EXCEPTIONS
370 try {
371#endif // _LIBCPP_HAS_EXCEPTIONS
372 if (c & locale::collate) {
373 install_from<std::collate<char> >(one);
348 __exception_guard guard([&] {
349 for (unsigned i = 0; i < facets_.size(); ++i)
350 if (facets_[i])
351 facets_[i]->__release_shared();
352 });
353
354 if (c & locale::collate) {
355 install_from<std::collate<char> >(one);
374356#if _LIBCPP_HAS_WIDE_CHARACTERS
375 install_from<std::collate<wchar_t> >(one);
357 install_from<std::collate<wchar_t> >(one);
376358#endif
377 }
378 if (c & locale::ctype) {
379 install_from<std::ctype<char> >(one);
359 }
360 if (c & locale::ctype) {
361 install_from<std::ctype<char> >(one);
380362#if _LIBCPP_HAS_WIDE_CHARACTERS
381 install_from<std::ctype<wchar_t> >(one);
363 install_from<std::ctype<wchar_t> >(one);
382364#endif
383 install_from<std::codecvt<char, char, mbstate_t> >(one);
384 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
385 install_from<std::codecvt<char16_t, char, mbstate_t> >(one);
386 install_from<std::codecvt<char32_t, char, mbstate_t> >(one);
387 _LIBCPP_SUPPRESS_DEPRECATED_POP
365 install_from<std::codecvt<char, char, mbstate_t> >(one);
366 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
367 install_from<std::codecvt<char16_t, char, mbstate_t> >(one);
368 install_from<std::codecvt<char32_t, char, mbstate_t> >(one);
369 _LIBCPP_SUPPRESS_DEPRECATED_POP
388370#if _LIBCPP_HAS_CHAR8_T
389 install_from<std::codecvt<char16_t, char8_t, mbstate_t> >(one);
390 install_from<std::codecvt<char32_t, char8_t, mbstate_t> >(one);
371 install_from<std::codecvt<char16_t, char8_t, mbstate_t> >(one);
372 install_from<std::codecvt<char32_t, char8_t, mbstate_t> >(one);
391373#endif
392374#if _LIBCPP_HAS_WIDE_CHARACTERS
393 install_from<std::codecvt<wchar_t, char, mbstate_t> >(one);
375 install_from<std::codecvt<wchar_t, char, mbstate_t> >(one);
394376#endif
395 }
396 if (c & locale::monetary) {
397 install_from<moneypunct<char, false> >(one);
398 install_from<moneypunct<char, true> >(one);
377 }
378 if (c & locale::monetary) {
379 install_from<moneypunct<char, false> >(one);
380 install_from<moneypunct<char, true> >(one);
399381#if _LIBCPP_HAS_WIDE_CHARACTERS
400 install_from<moneypunct<wchar_t, false> >(one);
401 install_from<moneypunct<wchar_t, true> >(one);
382 install_from<moneypunct<wchar_t, false> >(one);
383 install_from<moneypunct<wchar_t, true> >(one);
402384#endif
403 install_from<money_get<char> >(one);
385 install_from<money_get<char> >(one);
404386#if _LIBCPP_HAS_WIDE_CHARACTERS
405 install_from<money_get<wchar_t> >(one);
387 install_from<money_get<wchar_t> >(one);
406388#endif
407 install_from<money_put<char> >(one);
389 install_from<money_put<char> >(one);
408390#if _LIBCPP_HAS_WIDE_CHARACTERS
409 install_from<money_put<wchar_t> >(one);
391 install_from<money_put<wchar_t> >(one);
410392#endif
411 }
412 if (c & locale::numeric) {
413 install_from<numpunct<char> >(one);
393 }
394 if (c & locale::numeric) {
395 install_from<numpunct<char> >(one);
414396#if _LIBCPP_HAS_WIDE_CHARACTERS
415 install_from<numpunct<wchar_t> >(one);
397 install_from<numpunct<wchar_t> >(one);
416398#endif
417 install_from<num_get<char> >(one);
399 install_from<num_get<char> >(one);
418400#if _LIBCPP_HAS_WIDE_CHARACTERS
419 install_from<num_get<wchar_t> >(one);
401 install_from<num_get<wchar_t> >(one);
420402#endif
421 install_from<num_put<char> >(one);
403 install_from<num_put<char> >(one);
422404#if _LIBCPP_HAS_WIDE_CHARACTERS
423 install_from<num_put<wchar_t> >(one);
405 install_from<num_put<wchar_t> >(one);
424406#endif
425 }
426 if (c & locale::time) {
427 install_from<time_get<char> >(one);
407 }
408 if (c & locale::time) {
409 install_from<time_get<char> >(one);
428410#if _LIBCPP_HAS_WIDE_CHARACTERS
429 install_from<time_get<wchar_t> >(one);
411 install_from<time_get<wchar_t> >(one);
430412#endif
431 install_from<time_put<char> >(one);
413 install_from<time_put<char> >(one);
432414#if _LIBCPP_HAS_WIDE_CHARACTERS
433 install_from<time_put<wchar_t> >(one);
415 install_from<time_put<wchar_t> >(one);
434416#endif
435 }
436 if (c & locale::messages) {
437 install_from<std::messages<char> >(one);
417 }
418 if (c & locale::messages) {
419 install_from<std::messages<char> >(one);
438420#if _LIBCPP_HAS_WIDE_CHARACTERS
439 install_from<std::messages<wchar_t> >(one);
421 install_from<std::messages<wchar_t> >(one);
440422#endif
441 }
442#if _LIBCPP_HAS_EXCEPTIONS
443 } catch (...) {
444 for (unsigned i = 0; i < facets_.size(); ++i)
445 if (facets_[i])
446 facets_[i]->__release_shared();
447 throw;
448423 }
449#endif // _LIBCPP_HAS_EXCEPTIONS
424 guard.__complete();
450425}
451426
452427locale::__imp::__imp(const __imp& other, facet* f, long id)
......@@ -933,7 +908,7 @@ const ctype<char>::mask* ctype<char>::classic_table() noexcept {
933908 return __pctype_func();
934909# elif defined(__EMSCRIPTEN__)
935910 return *__ctype_b_loc();
936# elif defined(_NEWLIB_VERSION)
911# elif _LIBCPP_LIBC_NEWLIB
937912 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
938913 return _ctype_ + 1;
939914# elif defined(_AIX)
......@@ -3961,13 +3936,7 @@ wstring numpunct<wchar_t>::do_falsename() const { return L"false"; }
39613936
39623937// numpunct_byname<char>
39633938
3964numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs) : numpunct<char>(refs) { __init(nm); }
3965
3966numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs) : numpunct<char>(refs) { __init(nm.c_str()); }
3967
3968numpunct_byname<char>::~numpunct_byname() {}
3969
3970void numpunct_byname<char>::__init(const char* nm) {
3939numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs) : numpunct<char>(refs) {
39713940 typedef numpunct<char> base;
39723941 if (strcmp(nm, "C") != 0) {
39733942 __libcpp_unique_locale loc(nm);
......@@ -3988,18 +3957,14 @@ void numpunct_byname<char>::__init(const char* nm) {
39883957 }
39893958}
39903959
3991// numpunct_byname<wchar_t>
3992
3993#if _LIBCPP_HAS_WIDE_CHARACTERS
3994numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs) : numpunct<wchar_t>(refs) { __init(nm); }
3960numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs) : numpunct_byname<char>(nm.c_str(), refs) {}
39953961
3996numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs) : numpunct<wchar_t>(refs) {
3997 __init(nm.c_str());
3998}
3962numpunct_byname<char>::~numpunct_byname() {}
39993963
4000numpunct_byname<wchar_t>::~numpunct_byname() {}
3964// numpunct_byname<wchar_t>
40013965
4002void numpunct_byname<wchar_t>::__init(const char* nm) {
3966#if _LIBCPP_HAS_WIDE_CHARACTERS
3967numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs) : numpunct<wchar_t>(refs) {
40033968 if (strcmp(nm, "C") != 0) {
40043969 __libcpp_unique_locale loc(nm);
40053970 if (!loc)
......@@ -4016,6 +3981,10 @@ void numpunct_byname<wchar_t>::__init(const char* nm) {
40163981 // localization for truename and falsename is not available
40173982 }
40183983}
3984
3985numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs) : numpunct_byname<wchar_t>(nm.c_str(), refs) {}
3986
3987numpunct_byname<wchar_t>::~numpunct_byname() {}
40193988#endif // _LIBCPP_HAS_WIDE_CHARACTERS
40203989
40213990// num_get helpers
......@@ -4383,7 +4352,7 @@ string __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct) {
43834352 char f[3] = {0};
43844353 f[0] = '%';
43854354 f[1] = fmt;
4386 size_t n = __locale::__strftime(buf, countof(buf), f, &t, __loc_);
4355 size_t n = __locale::__strftime(buf, std::size(buf), f, &t, __loc_);
43874356 char* bb = buf;
43884357 char* be = buf + n;
43894358 string result;
......@@ -4514,12 +4483,12 @@ wstring __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& c
45144483 char f[3] = {0};
45154484 f[0] = '%';
45164485 f[1] = fmt;
4517 __locale::__strftime(buf, countof(buf), f, &t, __loc_);
4486 __locale::__strftime(buf, std::size(buf), f, &t, __loc_);
45184487 wchar_t wbuf[100];
45194488 wchar_t* wbb = wbuf;
45204489 mbstate_t mb = {0};
45214490 const char* bb = buf;
4522 size_t j = __locale::__mbsrtowcs(wbb, &bb, countof(wbuf), &mb, __loc_);
4491 size_t j = __locale::__mbsrtowcs(wbb, &bb, std::size(wbuf), &mb, __loc_);
45234492 if (j == size_t(-1))
45244493 std::__throw_runtime_error("locale not supported");
45254494 wchar_t* wbe = wbb + j;
......@@ -4640,25 +4609,25 @@ void __time_get_storage<char>::init(const ctype<char>& ct) {
46404609 // __weeks_
46414610 for (int i = 0; i < 7; ++i) {
46424611 t.tm_wday = i;
4643 __locale::__strftime(buf, countof(buf), "%A", &t, __loc_);
4612 __locale::__strftime(buf, std::size(buf), "%A", &t, __loc_);
46444613 __weeks_[i] = buf;
4645 __locale::__strftime(buf, countof(buf), "%a", &t, __loc_);
4614 __locale::__strftime(buf, std::size(buf), "%a", &t, __loc_);
46464615 __weeks_[i + 7] = buf;
46474616 }
46484617 // __months_
46494618 for (int i = 0; i < 12; ++i) {
46504619 t.tm_mon = i;
4651 __locale::__strftime(buf, countof(buf), "%B", &t, __loc_);
4620 __locale::__strftime(buf, std::size(buf), "%B", &t, __loc_);
46524621 __months_[i] = buf;
4653 __locale::__strftime(buf, countof(buf), "%b", &t, __loc_);
4622 __locale::__strftime(buf, std::size(buf), "%b", &t, __loc_);
46544623 __months_[i + 12] = buf;
46554624 }
46564625 // __am_pm_
46574626 t.tm_hour = 1;
4658 __locale::__strftime(buf, countof(buf), "%p", &t, __loc_);
4627 __locale::__strftime(buf, std::size(buf), "%p", &t, __loc_);
46594628 __am_pm_[0] = buf;
46604629 t.tm_hour = 13;
4661 __locale::__strftime(buf, countof(buf), "%p", &t, __loc_);
4630 __locale::__strftime(buf, std::size(buf), "%p", &t, __loc_);
46624631 __am_pm_[1] = buf;
46634632 __c_ = __analyze('c', ct);
46644633 __r_ = __analyze('r', ct);
......@@ -4677,18 +4646,18 @@ void __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) {
46774646 // __weeks_
46784647 for (int i = 0; i < 7; ++i) {
46794648 t.tm_wday = i;
4680 __locale::__strftime(buf, countof(buf), "%A", &t, __loc_);
4649 __locale::__strftime(buf, std::size(buf), "%A", &t, __loc_);
46814650 mb = mbstate_t();
46824651 const char* bb = buf;
4683 size_t j = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, __loc_);
4652 size_t j = __locale::__mbsrtowcs(wbuf, &bb, std::size(wbuf), &mb, __loc_);
46844653 if (j == size_t(-1) || j == 0)
46854654 std::__throw_runtime_error("locale not supported");
46864655 wbe = wbuf + j;
46874656 __weeks_[i].assign(wbuf, wbe);
4688 __locale::__strftime(buf, countof(buf), "%a", &t, __loc_);
4657 __locale::__strftime(buf, std::size(buf), "%a", &t, __loc_);
46894658 mb = mbstate_t();
46904659 bb = buf;
4691 j = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, __loc_);
4660 j = __locale::__mbsrtowcs(wbuf, &bb, std::size(wbuf), &mb, __loc_);
46924661 if (j == size_t(-1) || j == 0)
46934662 std::__throw_runtime_error("locale not supported");
46944663 wbe = wbuf + j;
......@@ -4697,18 +4666,18 @@ void __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) {
46974666 // __months_
46984667 for (int i = 0; i < 12; ++i) {
46994668 t.tm_mon = i;
4700 __locale::__strftime(buf, countof(buf), "%B", &t, __loc_);
4669 __locale::__strftime(buf, std::size(buf), "%B", &t, __loc_);
47014670 mb = mbstate_t();
47024671 const char* bb = buf;
4703 size_t j = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, __loc_);
4672 size_t j = __locale::__mbsrtowcs(wbuf, &bb, std::size(wbuf), &mb, __loc_);
47044673 if (j == size_t(-1) || j == 0)
47054674 std::__throw_runtime_error("locale not supported");
47064675 wbe = wbuf + j;
47074676 __months_[i].assign(wbuf, wbe);
4708 __locale::__strftime(buf, countof(buf), "%b", &t, __loc_);
4677 __locale::__strftime(buf, std::size(buf), "%b", &t, __loc_);
47094678 mb = mbstate_t();
47104679 bb = buf;
4711 j = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, __loc_);
4680 j = __locale::__mbsrtowcs(wbuf, &bb, std::size(wbuf), &mb, __loc_);
47124681 if (j == size_t(-1) || j == 0)
47134682 std::__throw_runtime_error("locale not supported");
47144683 wbe = wbuf + j;
......@@ -4716,19 +4685,19 @@ void __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) {
47164685 }
47174686 // __am_pm_
47184687 t.tm_hour = 1;
4719 __locale::__strftime(buf, countof(buf), "%p", &t, __loc_);
4688 __locale::__strftime(buf, std::size(buf), "%p", &t, __loc_);
47204689 mb = mbstate_t();
47214690 const char* bb = buf;
4722 size_t j = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, __loc_);
4691 size_t j = __locale::__mbsrtowcs(wbuf, &bb, std::size(wbuf), &mb, __loc_);
47234692 if (j == size_t(-1))
47244693 std::__throw_runtime_error("locale not supported");
47254694 wbe = wbuf + j;
47264695 __am_pm_[0].assign(wbuf, wbe);
47274696 t.tm_hour = 13;
4728 __locale::__strftime(buf, countof(buf), "%p", &t, __loc_);
4697 __locale::__strftime(buf, std::size(buf), "%p", &t, __loc_);
47294698 mb = mbstate_t();
47304699 bb = buf;
4731 j = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, __loc_);
4700 j = __locale::__mbsrtowcs(wbuf, &bb, std::size(wbuf), &mb, __loc_);
47324701 if (j == size_t(-1))
47334702 std::__throw_runtime_error("locale not supported");
47344703 wbe = wbuf + j;
......@@ -4957,7 +4926,7 @@ void __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm, char __fmt, c
49574926 char fmt[] = {'%', __fmt, __mod, 0};
49584927 if (__mod != 0)
49594928 swap(fmt[1], fmt[2]);
4960 size_t n = __locale::__strftime(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
4929 size_t n = __locale::__strftime(__nb, std::distance(__nb, __ne), fmt, __tm, __loc_);
49614930 __ne = __nb + n;
49624931}
49634932
......@@ -4968,7 +4937,7 @@ void __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, char __
49684937 __do_put(__nar, __ne, __tm, __fmt, __mod);
49694938 mbstate_t mb = {0};
49704939 const char* __nb = __nar;
4971 size_t j = __locale::__mbsrtowcs(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
4940 size_t j = __locale::__mbsrtowcs(__wb, &__nb, std::distance(__wb, __we), &mb, __loc_);
49724941 if (j == size_t(-1))
49734942 std::__throw_runtime_error("locale not supported");
49744943 __we = __wb + j;
......@@ -5443,7 +5412,7 @@ void moneypunct_byname<wchar_t, false>::init(const char* nm) {
54435412 wchar_t wbuf[100];
54445413 mbstate_t mb = {0};
54455414 const char* bb = lc->currency_symbol;
5446 size_t j = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, loc.get());
5415 size_t j = __locale::__mbsrtowcs(wbuf, &bb, std::size(wbuf), &mb, loc.get());
54475416 if (j == size_t(-1))
54485417 std::__throw_runtime_error("locale not supported");
54495418 wchar_t* wbe = wbuf + j;
......@@ -5457,7 +5426,7 @@ void moneypunct_byname<wchar_t, false>::init(const char* nm) {
54575426 else {
54585427 mb = mbstate_t();
54595428 bb = lc->positive_sign;
5460 j = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, loc.get());
5429 j = __locale::__mbsrtowcs(wbuf, &bb, std::size(wbuf), &mb, loc.get());
54615430 if (j == size_t(-1))
54625431 std::__throw_runtime_error("locale not supported");
54635432 wbe = wbuf + j;
......@@ -5468,7 +5437,7 @@ void moneypunct_byname<wchar_t, false>::init(const char* nm) {
54685437 else {
54695438 mb = mbstate_t();
54705439 bb = lc->negative_sign;
5471 j = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, loc.get());
5440 j = __locale::__mbsrtowcs(wbuf, &bb, std::size(wbuf), &mb, loc.get());
54725441 if (j == size_t(-1))
54735442 std::__throw_runtime_error("locale not supported");
54745443 wbe = wbuf + j;
......@@ -5498,7 +5467,7 @@ void moneypunct_byname<wchar_t, true>::init(const char* nm) {
54985467 wchar_t wbuf[100];
54995468 mbstate_t mb = {0};
55005469 const char* bb = lc->int_curr_symbol;
5501 size_t j = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, loc.get());
5470 size_t j = __locale::__mbsrtowcs(wbuf, &bb, std::size(wbuf), &mb, loc.get());
55025471 if (j == size_t(-1))
55035472 std::__throw_runtime_error("locale not supported");
55045473 wchar_t* wbe = wbuf + j;
......@@ -5516,7 +5485,7 @@ void moneypunct_byname<wchar_t, true>::init(const char* nm) {
55165485 else {
55175486 mb = mbstate_t();
55185487 bb = lc->positive_sign;
5519 j = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, loc.get());
5488 j = __locale::__mbsrtowcs(wbuf, &bb, std::size(wbuf), &mb, loc.get());
55205489 if (j == size_t(-1))
55215490 std::__throw_runtime_error("locale not supported");
55225491 wbe = wbuf + j;
......@@ -5531,7 +5500,7 @@ void moneypunct_byname<wchar_t, true>::init(const char* nm) {
55315500 else {
55325501 mb = mbstate_t();
55335502 bb = lc->negative_sign;
5534 j = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, loc.get());
5503 j = __locale::__mbsrtowcs(wbuf, &bb, std::size(wbuf), &mb, loc.get());
55355504 if (j == size_t(-1))
55365505 std::__throw_runtime_error("locale not supported");
55375506 wbe = wbuf + j;
......@@ -5571,6 +5540,54 @@ string __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _C
55715540 return __np.grouping();
55725541}
55735542
5543template <class _CharT>
5544int __num_get<_CharT>::__stage2_int_loop(
5545 _CharT __ct,
5546 int __base,
5547 char* __a,
5548 char*& __a_end,
5549 unsigned& __dc,
5550 _CharT __thousands_sep,
5551 const string& __grouping,
5552 unsigned* __g,
5553 unsigned*& __g_end,
5554 _CharT* __atoms) {
5555 if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) {
5556 *__a_end++ = __ct == __atoms[24] ? '+' : '-';
5557 __dc = 0;
5558 return 0;
5559 }
5560 if (__grouping.size() != 0 && __ct == __thousands_sep) {
5561 if (__g_end - __g < __num_get_buf_sz) {
5562 *__g_end++ = __dc;
5563 __dc = 0;
5564 }
5565 return 0;
5566 }
5567 ptrdiff_t __f = __atoms_offset(__atoms, __ct);
5568 if (__f >= 24)
5569 return -1;
5570 switch (__base) {
5571 case 8:
5572 case 10:
5573 if (__f >= __base)
5574 return -1;
5575 break;
5576 case 16:
5577 if (__f < 22)
5578 break;
5579 if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') {
5580 __dc = 0;
5581 *__a_end++ = __src[__f];
5582 return 0;
5583 }
5584 return -1;
5585 }
5586 *__a_end++ = __src[__f];
5587 ++__dc;
5588 return 0;
5589}
5590
55745591template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
55755592_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;)
55765593
lib/libcxx/src/memory.cpp+12-14
......@@ -7,7 +7,8 @@
77//===----------------------------------------------------------------------===//
88
99#include <__config>
10#ifdef _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS
10#if !defined(_LIBCPP_OBJECT_FORMAT_COFF) && !defined(_LIBCPP_OBJECT_FORMAT_XCOFF) && \
11 _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 5
1112# define _LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS
1213#endif
1314
......@@ -132,19 +133,16 @@ __sp_mut& __get_sp_mut(const void* p) {
132133
133134#endif // _LIBCPP_HAS_THREADS
134135
135void* align(size_t alignment, size_t size, void*& ptr, size_t& space) {
136 void* r = nullptr;
137 if (size <= space) {
138 char* p1 = static_cast<char*>(ptr);
139 char* p2 = reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(p1 + (alignment - 1)) & -alignment);
140 size_t d = static_cast<size_t>(p2 - p1);
141 if (d <= space - size) {
142 r = p2;
143 ptr = r;
144 space -= d;
145 }
146 }
147 return r;
136#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 21
137
138_LIBCPP_DIAGNOSTIC_PUSH
139_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-prototypes")
140// This function only exists for ABI compatibility and we therefore don't provide a declaration in the headers
141_LIBCPP_EXPORTED_FROM_ABI void* align(size_t alignment, size_t size, void*& ptr, size_t& space) {
142 return __align_inline::align(alignment, size, ptr, space);
148143}
144_LIBCPP_DIAGNOSTIC_POP
145
146#endif
149147
150148_LIBCPP_END_NAMESPACE_STD
lib/libcxx/src/mutex_destructor.cpp+1-1
......@@ -19,7 +19,7 @@
1919#include <__config>
2020#include <__thread/support.h>
2121
22#if _LIBCPP_ABI_VERSION == 1 || !_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION
22#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 9 || !_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION
2323# define NEEDS_MUTEX_DESTRUCTOR
2424#endif
2525
lib/libcxx/src/new.cpp+5-5
......@@ -6,9 +6,9 @@
66//
77//===----------------------------------------------------------------------===//
88
9#include "include/aligned_alloc.h"
910#include "include/overridable_function.h"
1011#include <__assert>
11#include <__memory/aligned_alloc.h>
1212#include <cstddef>
1313#include <cstdlib>
1414#include <new>
......@@ -43,7 +43,7 @@ static void* operator_new_impl(std::size_t size) {
4343 return p;
4444}
4545
46_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new, (std::size_t size)) _THROW_BAD_ALLOC {
46OVERRIDABLE_FUNCTION void* operator new(std::size_t size) _THROW_BAD_ALLOC {
4747 void* p = operator_new_impl(size);
4848 if (p == nullptr)
4949 __throw_bad_alloc_shim();
......@@ -74,7 +74,7 @@ _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
7474# endif
7575}
7676
77_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new[], (size_t size)) _THROW_BAD_ALLOC { return ::operator new(size); }
77OVERRIDABLE_FUNCTION void* operator new[](size_t size) _THROW_BAD_ALLOC { return ::operator new(size); }
7878
7979_LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept {
8080# if !_LIBCPP_HAS_EXCEPTIONS
......@@ -134,7 +134,7 @@ static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignm
134134 return p;
135135}
136136
137_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new, (std::size_t size, std::align_val_t alignment)) _THROW_BAD_ALLOC {
137OVERRIDABLE_FUNCTION void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
138138 void* p = operator_new_aligned_impl(size, alignment);
139139 if (p == nullptr)
140140 __throw_bad_alloc_shim();
......@@ -165,7 +165,7 @@ _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const s
165165# endif
166166}
167167
168_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new[], (size_t size, std::align_val_t alignment)) _THROW_BAD_ALLOC {
168OVERRIDABLE_FUNCTION void* operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
169169 return ::operator new(size, alignment);
170170}
171171
lib/libcxx/src/optional.cpp+4
......@@ -19,6 +19,8 @@ const char* bad_optional_access::what() const noexcept { return "bad_optional_ac
1919
2020#include <__config>
2121
22#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 7
23
2224// Preserve std::experimental::bad_optional_access for ABI compatibility
2325// Even though it no longer exists in a header file
2426_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
......@@ -34,3 +36,5 @@ public:
3436bad_optional_access::~bad_optional_access() noexcept = default;
3537
3638_LIBCPP_END_NAMESPACE_EXPERIMENTAL
39
40#endif // _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 7
lib/libcxx/src/print.cpp+9-1
......@@ -22,6 +22,14 @@
2222# include <windows.h>
2323#elif __has_include(<unistd.h>)
2424# include <unistd.h>
25# if defined(_NEWLIB_VERSION)
26# if defined(_POSIX_C_SOURCE) && __has_include(<stdio.h>)
27# include <stdio.h>
28# define HAS_FILENO_AND_ISATTY
29# endif
30# else
31# define HAS_FILENO_AND_ISATTY
32# endif
2533#endif
2634
2735_LIBCPP_BEGIN_NAMESPACE_STD
......@@ -56,7 +64,7 @@ __write_to_windows_console([[maybe_unused]] FILE* __stream, [[maybe_unused]] wst
5664}
5765# endif // _LIBCPP_HAS_WIDE_CHARACTERS
5866
59#elif __has_include(<unistd.h>) // !_LIBCPP_WIN32API
67#elif defined(HAS_FILENO_AND_ISATTY) // !_LIBCPP_WIN32API
6068
6169_LIBCPP_EXPORTED_FROM_ABI bool __is_posix_terminal(FILE* __stream) { return isatty(fileno(__stream)); }
6270#endif
lib/libcxx/src/random.cpp-26
......@@ -31,8 +31,6 @@
3131# include <linux/random.h>
3232# include <sys/ioctl.h>
3333# endif
34#elif defined(_LIBCPP_USING_NACL_RANDOM)
35# include <nacl/nacl_random.h>
3634#elif defined(_LIBCPP_USING_FUCHSIA_CPRNG)
3735# include <zircon/syscalls.h>
3836#endif
......@@ -93,30 +91,6 @@ unsigned random_device::operator()() {
9391 return r;
9492}
9593
96#elif defined(_LIBCPP_USING_NACL_RANDOM)
97
98random_device::random_device(const string& __token) {
99 if (__token != "/dev/urandom")
100 std::__throw_system_error(ENOENT, ("random device not supported " + __token).c_str());
101 int error = nacl_secure_random_init();
102 if (error)
103 std::__throw_system_error(error, ("random device failed to open " + __token).c_str());
104}
105
106random_device::~random_device() {}
107
108unsigned random_device::operator()() {
109 unsigned r;
110 size_t n = sizeof(r);
111 size_t bytes_written;
112 int error = nacl_secure_random(&r, n, &bytes_written);
113 if (error != 0)
114 std::__throw_system_error(error, "random_device failed getting bytes");
115 else if (bytes_written != n)
116 std::__throw_runtime_error("random_device failed to obtain enough bytes");
117 return r;
118}
119
12094#elif defined(_LIBCPP_USING_WIN32_RANDOM)
12195
12296random_device::random_device(const string& __token) {
lib/libcxx/src/string.cpp+10-25
......@@ -20,7 +20,7 @@
2020
2121_LIBCPP_BEGIN_NAMESPACE_STD
2222
23#ifndef _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON
23#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 14
2424
2525template <bool>
2626struct __basic_string_common;
......@@ -35,45 +35,30 @@ struct __basic_string_common<true> {
3535void __basic_string_common<true>::__throw_length_error() const { std::__throw_length_error("basic_string"); }
3636void __basic_string_common<true>::__throw_out_of_range() const { std::__throw_out_of_range("basic_string"); }
3737
38#endif // _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON
38#endif // _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 14
3939
4040// Define legacy ABI functions
4141// ---------------------------
4242
43#ifndef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
43#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 21
4444
45// This initializes the string with [__s, __s + __sz), but capacity() == __reserve. Assumes that __reserve >= __sz.
4546template <class _CharT, class _Traits, class _Allocator>
4647void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve) {
47 if (__libcpp_is_constant_evaluated())
48 __rep_ = __rep();
49 if (__reserve > max_size())
50 __throw_length_error();
51 pointer __p;
52 if (__fits_in_sso(__reserve)) {
53 __set_short_size(__sz);
54 __p = __get_short_pointer();
55 } else {
56 auto __allocation = std::__allocate_at_least(__alloc_, __recommend(__reserve) + 1);
57 __p = __allocation.ptr;
58 __begin_lifetime(__p, __allocation.count);
59 __set_long_pointer(__p);
60 __set_long_cap(__allocation.count);
61 __set_long_size(__sz);
62 }
48 pointer __p = __init_internal_buffer(__reserve);
49 __annotate_delete();
50 __set_size(__sz);
6351 traits_type::copy(std::__to_address(__p), __s, __sz);
6452 traits_type::assign(__p[__sz], value_type());
6553 __annotate_new(__sz);
6654}
6755
68# define STRING_LEGACY_API(CharT) \
69 template _LIBCPP_EXPORTED_FROM_ABI void basic_string<CharT>::__init(const value_type*, size_type, size_type)
70
71STRING_LEGACY_API(char);
56template _LIBCPP_EXPORTED_FROM_ABI void basic_string<char>::__init(const value_type*, size_type, size_type);
7257# if _LIBCPP_HAS_WIDE_CHARACTERS
73STRING_LEGACY_API(wchar_t);
58template _LIBCPP_EXPORTED_FROM_ABI void basic_string<wchar_t>::__init(const value_type*, size_type, size_type);
7459# endif
7560
76#endif // _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
61#endif // _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 21
7762
7863#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template _LIBCPP_EXPORTED_FROM_ABI __VA_ARGS__;
7964#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
lib/libcxx/src/support/runtime/exception_fallback.ipp+2
......@@ -8,6 +8,8 @@
88//===----------------------------------------------------------------------===//
99
1010#include <__verbose_abort>
11#include <exception>
12#include "include/atomic_support.h"
1113
1214namespace std {
1315
lib/libcxx/src/support/runtime/exception_glibcxx.ipp+3
......@@ -11,6 +11,9 @@
1111# error header can only be used when targeting libstdc++ or libsupc++
1212#endif
1313
14#include <exception>
15#include <new>
16
1417namespace std {
1518
1619bad_alloc::bad_alloc() noexcept {}
lib/libcxx/src/support/runtime/exception_libcxxabi.ipp+6-2
......@@ -7,6 +7,10 @@
77//
88//===----------------------------------------------------------------------===//
99
10#include <exception>
11
12#include <cxxabi.h>
13
1014#ifndef _LIBCPPABI_VERSION
1115# error this header can only be used with libc++abi
1216#endif
......@@ -17,9 +21,9 @@ bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; }
1721
1822int uncaught_exceptions() noexcept {
1923#if _LIBCPPABI_VERSION > 1001
20 return __cxa_uncaught_exceptions();
24 return abi::__cxa_uncaught_exceptions();
2125#else
22 return __cxa_uncaught_exception() ? 1 : 0;
26 return abi::__cxa_uncaught_exception() ? 1 : 0;
2327#endif
2428}
2529
lib/libcxx/src/support/runtime/exception_libcxxrt.ipp+2
......@@ -11,6 +11,8 @@
1111# error this header may only be used when targeting libcxxrt
1212#endif
1313
14#include <exception>
15
1416namespace std {
1517
1618bad_exception::~bad_exception() noexcept {}
lib/libcxx/src/support/runtime/exception_msvc.ipp+2
......@@ -12,6 +12,8 @@
1212#endif
1313
1414#include <__verbose_abort>
15#include <exception>
16#include <new>
1517
1618extern "C" {
1719typedef void(__cdecl* terminate_handler)();
lib/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp+9-10
......@@ -7,22 +7,21 @@
77//
88//===----------------------------------------------------------------------===//
99
10#ifndef HAVE_DEPENDENT_EH_ABI
11# error this header may only be used with libc++abi or libcxxrt
12#endif
10#include <cxxabi.h>
11#include <exception>
1312
1413namespace std {
1514
16exception_ptr::~exception_ptr() noexcept { __cxa_decrement_exception_refcount(__ptr_); }
15exception_ptr::~exception_ptr() noexcept { abi::__cxa_decrement_exception_refcount(__ptr_); }
1716
1817exception_ptr::exception_ptr(const exception_ptr& other) noexcept : __ptr_(other.__ptr_) {
19 __cxa_increment_exception_refcount(__ptr_);
18 abi::__cxa_increment_exception_refcount(__ptr_);
2019}
2120
2221exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
2322 if (__ptr_ != other.__ptr_) {
24 __cxa_increment_exception_refcount(other.__ptr_);
25 __cxa_decrement_exception_refcount(__ptr_);
23 abi::__cxa_increment_exception_refcount(other.__ptr_);
24 abi::__cxa_decrement_exception_refcount(__ptr_);
2625 __ptr_ = other.__ptr_;
2726 }
2827 return *this;
......@@ -31,7 +30,7 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
3130exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept {
3231 exception_ptr ptr;
3332 ptr.__ptr_ = __e;
34 __cxa_increment_exception_refcount(ptr.__ptr_);
33 abi::__cxa_increment_exception_refcount(ptr.__ptr_);
3534
3635 return ptr;
3736}
......@@ -51,12 +50,12 @@ exception_ptr current_exception() noexcept {
5150 // this whole function would be just:
5251 // return exception_ptr(__cxa_current_primary_exception());
5352 exception_ptr ptr;
54 ptr.__ptr_ = __cxa_current_primary_exception();
53 ptr.__ptr_ = abi::__cxa_current_primary_exception();
5554 return ptr;
5655}
5756
5857void rethrow_exception(exception_ptr p) {
59 __cxa_rethrow_primary_exception(p.__ptr_);
58 abi::__cxa_rethrow_primary_exception(p.__ptr_);
6059 // if p.__ptr_ is NULL, above returns so we terminate
6160 terminate();
6261}
lib/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp+2
......@@ -16,6 +16,8 @@
1616// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr)
1717// function.
1818
19#include <exception>
20
1921namespace std {
2022
2123namespace __exception_ptr {
lib/libcxx/src/support/runtime/exception_pointer_msvc.ipp+1
......@@ -7,6 +7,7 @@
77//
88//===----------------------------------------------------------------------===//
99
10#include <exception>
1011#include <stdio.h>
1112#include <stdlib.h>
1213
lib/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp+1
......@@ -8,6 +8,7 @@
88//===----------------------------------------------------------------------===//
99
1010#include <__verbose_abort>
11#include <exception>
1112
1213namespace std {
1314
lib/libcxx/src/support/win32/locale_win32.cpp+1-1
......@@ -144,7 +144,7 @@ int __snprintf(char* ret, size_t n, __locale_t loc, const char* format, ...) {
144144// Like sprintf, but when return value >= 0 it returns
145145// a pointer to a malloc'd string in *sptr.
146146// If return >= 0, use free to delete *sptr.
147int __libcpp_vasprintf(char** sptr, const char* __restrict format, va_list ap) {
147static int __libcpp_vasprintf(char** sptr, const char* __restrict format, va_list ap) {
148148 *sptr = nullptr;
149149 // Query the count required.
150150 va_list ap_copy;
lib/libcxx/src/system_error.cpp+2
......@@ -95,6 +95,8 @@ std::optional<errc> __win_err_to_errc(int err) {
9595 return errc::no_lock_available;
9696 case ERROR_NEGATIVE_SEEK:
9797 return errc::invalid_argument;
98 case ERROR_NETNAME_DELETED:
99 return errc::no_such_file_or_directory;
98100 case ERROR_NOACCESS:
99101 return errc::permission_denied;
100102 case ERROR_NOT_ENOUGH_MEMORY:
lib/libcxx/src/thread.cpp+1-3
......@@ -74,9 +74,7 @@ unsigned thread::hardware_concurrency() noexcept {
7474 return 0;
7575 return static_cast<unsigned>(result);
7676#elif defined(_LIBCPP_WIN32API)
77 SYSTEM_INFO info;
78 GetSystemInfo(&info);
79 return info.dwNumberOfProcessors;
77 return static_cast<unsigned>(GetActiveProcessorCount(ALL_PROCESSOR_GROUPS));
8078#else // defined(CTL_HW) && defined(HW_NCPU)
8179 // TODO: grovel through /proc or check cpuid on x86 and similar
8280 // instructions on other architectures.
lib/libcxx/src/valarray.cpp+1-2
......@@ -10,8 +10,7 @@
1010
1111_LIBCPP_BEGIN_NAMESPACE_STD
1212
13// These two symbols are part of the v1 ABI but not part of the >=v2 ABI.
14#if _LIBCPP_ABI_VERSION == 1
13#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 9
1514template _LIBCPP_EXPORTED_FROM_ABI valarray<size_t>::valarray(size_t);
1615template _LIBCPP_EXPORTED_FROM_ABI valarray<size_t>::~valarray();
1716#endif
lib/libcxx/src/vector.cpp+2-2
......@@ -10,7 +10,7 @@
1010
1111_LIBCPP_BEGIN_NAMESPACE_STD
1212
13#ifndef _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
13#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 15
1414
1515template <bool>
1616struct __vector_base_common;
......@@ -25,6 +25,6 @@ void __vector_base_common<true>::__throw_length_error() const { std::__throw_len
2525
2626void __vector_base_common<true>::__throw_out_of_range() const { std::__throw_out_of_range("vector"); }
2727
28#endif // _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
28#endif // _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 15
2929
3030_LIBCPP_END_NAMESPACE_STD
src/libs/libcxx.zig+14-5
......@@ -538,11 +538,20 @@ pub fn addCxxArgs(
538538 // Compilation.addCCArgs. This option makes it use serial backend which
539539 // is simple and works everywhere.
540540 try cflags.append("-D_LIBCPP_PSTL_BACKEND_SERIAL");
541 try cflags.append(switch (optimize_mode) {
542 .Debug => "-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG",
543 .ReleaseFast, .ReleaseSmall => "-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE",
544 .ReleaseSafe => "-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST",
545 });
541 switch (optimize_mode) {
542 .Debug => {
543 try cflags.append("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG");
544 try cflags.append("-D_LIBCPP_ASSERTION_SEMANTIC_DEFAULT=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE");
545 },
546 .ReleaseFast, .ReleaseSmall => {
547 try cflags.append("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE");
548 try cflags.append("-D_LIBCPP_ASSERTION_SEMANTIC_DEFAULT=_LIBCPP_ASSERTION_SEMANTIC_IGNORE");
549 },
550 .ReleaseSafe => {
551 try cflags.append("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST");
552 try cflags.append("-D_LIBCPP_ASSERTION_SEMANTIC_DEFAULT=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE");
553 },
554 }
546555 if (target.isGnuLibC()) {
547556 // glibc 2.16 introduced aligned_alloc
548557 if (target.os.versionRange().gnuLibCVersion().?.order(.{ .major = 2, .minor = 16, .patch = 0 }) == .lt) {