aboutsummaryrefslogtreecommitdiff
path: root/libcxx
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx')
-rw-r--r--libcxx/include/__algorithm/binary_search.h10
-rw-r--r--libcxx/include/__algorithm/count.h4
-rw-r--r--libcxx/include/__algorithm/equal_range.h18
-rw-r--r--libcxx/include/__algorithm/fill.h12
-rw-r--r--libcxx/include/__algorithm/fill_n.h8
-rw-r--r--libcxx/include/__algorithm/find.h4
-rw-r--r--libcxx/include/__algorithm/find_end.h181
-rw-r--r--libcxx/include/__algorithm/iterator_operations.h68
-rw-r--r--libcxx/include/__algorithm/lower_bound.h15
-rw-r--r--libcxx/include/__algorithm/make_heap.h43
-rw-r--r--libcxx/include/__algorithm/make_projected.h22
-rw-r--r--libcxx/include/__algorithm/minmax_element.h8
-rw-r--r--libcxx/include/__algorithm/nth_element.h44
-rw-r--r--libcxx/include/__algorithm/partial_sort.h9
-rw-r--r--libcxx/include/__algorithm/pop_heap.h60
-rw-r--r--libcxx/include/__algorithm/push_heap.h71
-rw-r--r--libcxx/include/__algorithm/ranges_binary_search.h4
-rw-r--r--libcxx/include/__algorithm/ranges_equal_range.h74
-rw-r--r--libcxx/include/__algorithm/ranges_find_end.h113
-rw-r--r--libcxx/include/__algorithm/ranges_generate.h73
-rw-r--r--libcxx/include/__algorithm/ranges_generate_n.h65
-rw-r--r--libcxx/include/__algorithm/ranges_includes.h75
-rw-r--r--libcxx/include/__algorithm/ranges_inplace_merge.h73
-rw-r--r--libcxx/include/__algorithm/ranges_is_heap.h70
-rw-r--r--libcxx/include/__algorithm/ranges_is_heap_until.h71
-rw-r--r--libcxx/include/__algorithm/ranges_lower_bound.h4
-rw-r--r--libcxx/include/__algorithm/ranges_make_heap.h79
-rw-r--r--libcxx/include/__algorithm/ranges_merge.h142
-rw-r--r--libcxx/include/__algorithm/ranges_nth_element.h79
-rw-r--r--libcxx/include/__algorithm/ranges_partial_sort_copy.h88
-rw-r--r--libcxx/include/__algorithm/ranges_partition.h74
-rw-r--r--libcxx/include/__algorithm/ranges_partition_copy.h82
-rw-r--r--libcxx/include/__algorithm/ranges_partition_point.h71
-rw-r--r--libcxx/include/__algorithm/ranges_pop_heap.h80
-rw-r--r--libcxx/include/__algorithm/ranges_push_heap.h79
-rw-r--r--libcxx/include/__algorithm/ranges_remove.h64
-rw-r--r--libcxx/include/__algorithm/ranges_remove_copy.h81
-rw-r--r--libcxx/include/__algorithm/ranges_remove_copy_if.h80
-rw-r--r--libcxx/include/__algorithm/ranges_remove_if.h85
-rw-r--r--libcxx/include/__algorithm/ranges_replace_copy.h84
-rw-r--r--libcxx/include/__algorithm/ranges_replace_copy_if.h81
-rw-r--r--libcxx/include/__algorithm/ranges_reverse_copy.h67
-rw-r--r--libcxx/include/__algorithm/ranges_rotate_copy.h68
-rw-r--r--libcxx/include/__algorithm/ranges_search.h134
-rw-r--r--libcxx/include/__algorithm/ranges_search_n.h120
-rw-r--r--libcxx/include/__algorithm/ranges_set_difference.h104
-rw-r--r--libcxx/include/__algorithm/ranges_set_intersection.h117
-rw-r--r--libcxx/include/__algorithm/ranges_set_symmetric_difference.h116
-rw-r--r--libcxx/include/__algorithm/ranges_set_union.h86
-rw-r--r--libcxx/include/__algorithm/ranges_shuffle.h74
-rw-r--r--libcxx/include/__algorithm/ranges_sort_heap.h79
-rw-r--r--libcxx/include/__algorithm/ranges_stable_partition.h75
-rw-r--r--libcxx/include/__algorithm/ranges_unique.h74
-rw-r--r--libcxx/include/__algorithm/ranges_unique_copy.h88
-rw-r--r--libcxx/include/__algorithm/ranges_upper_bound.h4
-rw-r--r--libcxx/include/__algorithm/remove.h6
-rw-r--r--libcxx/include/__algorithm/remove_copy.h4
-rw-r--r--libcxx/include/__algorithm/search.h176
-rw-r--r--libcxx/include/__algorithm/search_n.h159
-rw-r--r--libcxx/include/__algorithm/set_difference.h81
-rw-r--r--libcxx/include/__algorithm/set_intersection.h101
-rw-r--r--libcxx/include/__algorithm/set_symmetric_difference.h111
-rw-r--r--libcxx/include/__algorithm/sort.h7
-rw-r--r--libcxx/include/__algorithm/sort_heap.h33
-rw-r--r--libcxx/include/__algorithm/upper_bound.h12
-rw-r--r--libcxx/include/__bit_reference16
-rw-r--r--libcxx/include/__bits17
-rw-r--r--libcxx/include/__charconv/tables.h50
-rw-r--r--libcxx/include/__charconv/to_chars_base_10.h60
-rw-r--r--libcxx/include/__chrono/day.h23
-rw-r--r--libcxx/include/__chrono/duration.h8
-rw-r--r--libcxx/include/__chrono/time_point.h4
-rw-r--r--libcxx/include/__chrono/year.h9
-rw-r--r--libcxx/include/__chrono/year_month_weekday.h8
-rw-r--r--libcxx/include/__config56
-rw-r--r--libcxx/include/__debug16
-rw-r--r--libcxx/include/__debug_utils/randomize_range.h42
-rw-r--r--libcxx/include/__filesystem/copy_options.h34
-rw-r--r--libcxx/include/__filesystem/directory_options.h46
-rw-r--r--libcxx/include/__filesystem/operations.h22
-rw-r--r--libcxx/include/__filesystem/perm_options.h34
-rw-r--r--libcxx/include/__filesystem/perms.h28
-rw-r--r--libcxx/include/__format/format_arg.h23
-rw-r--r--libcxx/include/__format/format_arg_store.h10
-rw-r--r--libcxx/include/__format/formatter.h227
-rw-r--r--libcxx/include/__format/formatter_bool.h1
-rw-r--r--libcxx/include/__format/formatter_char.h2
-rw-r--r--libcxx/include/__format/formatter_floating_point.h415
-rw-r--r--libcxx/include/__format/formatter_integer.h33
-rw-r--r--libcxx/include/__format/formatter_integral.h5
-rw-r--r--libcxx/include/__format/formatter_output.h59
-rw-r--r--libcxx/include/__format/parser_std_format_spec.h893
-rw-r--r--libcxx/include/__functional/default_searcher.h8
-rw-r--r--libcxx/include/__functional/function.h4
-rw-r--r--libcxx/include/__hash_table63
-rw-r--r--libcxx/include/__iterator/back_insert_iterator.h8
-rw-r--r--libcxx/include/__iterator/front_insert_iterator.h8
-rw-r--r--libcxx/include/__iterator/insert_iterator.h8
-rw-r--r--libcxx/include/__iterator/iterator_traits.h12
-rw-r--r--libcxx/include/__iterator/ostream_iterator.h4
-rw-r--r--libcxx/include/__iterator/reverse_iterator.h17
-rw-r--r--libcxx/include/__mutex_base12
-rw-r--r--libcxx/include/__numeric/iota.h6
-rw-r--r--libcxx/include/__random/piecewise_constant_distribution.h20
-rw-r--r--libcxx/include/__random/piecewise_linear_distribution.h20
-rw-r--r--libcxx/include/__ranges/zip_view.h8
-rw-r--r--libcxx/include/__split_buffer26
-rw-r--r--libcxx/include/__string/char_traits.h4
-rw-r--r--libcxx/include/__threading_support22
-rw-r--r--libcxx/include/__tree32
-rw-r--r--libcxx/include/__tuple6
-rw-r--r--libcxx/include/__type_traits/extent.h6
-rw-r--r--libcxx/include/__type_traits/has_virtual_destructor.h2
-rw-r--r--libcxx/include/__type_traits/is_array.h4
-rw-r--r--libcxx/include/__type_traits/is_assignable.h6
-rw-r--r--libcxx/include/__type_traits/is_compound.h6
-rw-r--r--libcxx/include/__type_traits/is_const.h4
-rw-r--r--libcxx/include/__type_traits/is_convertible.h6
-rw-r--r--libcxx/include/__type_traits/is_destructible.h6
-rw-r--r--libcxx/include/__type_traits/is_function.h4
-rw-r--r--libcxx/include/__type_traits/is_fundamental.h6
-rw-r--r--libcxx/include/__type_traits/is_integral.h4
-rw-r--r--libcxx/include/__type_traits/is_member_function_pointer.h6
-rw-r--r--libcxx/include/__type_traits/is_member_object_pointer.h6
-rw-r--r--libcxx/include/__type_traits/is_member_pointer.h6
-rw-r--r--libcxx/include/__type_traits/is_nothrow_assignable.h4
-rw-r--r--libcxx/include/__type_traits/is_nothrow_constructible.h4
-rw-r--r--libcxx/include/__type_traits/is_object.h6
-rw-r--r--libcxx/include/__type_traits/is_pod.h4
-rw-r--r--libcxx/include/__type_traits/is_pointer.h6
-rw-r--r--libcxx/include/__type_traits/is_reference.h10
-rw-r--r--libcxx/include/__type_traits/is_scalar.h6
-rw-r--r--libcxx/include/__type_traits/is_signed.h6
-rw-r--r--libcxx/include/__type_traits/is_standard_layout.h2
-rw-r--r--libcxx/include/__type_traits/is_trivial.h2
-rw-r--r--libcxx/include/__type_traits/is_trivially_destructible.h6
-rw-r--r--libcxx/include/__type_traits/is_unsigned.h6
-rw-r--r--libcxx/include/__type_traits/is_void.h4
-rw-r--r--libcxx/include/__type_traits/is_volatile.h4
-rw-r--r--libcxx/include/algorithm234
-rw-r--r--libcxx/include/any2
-rw-r--r--libcxx/include/array7
-rw-r--r--libcxx/include/atomic9
-rw-r--r--libcxx/include/barrier8
-rw-r--r--libcxx/include/charconv135
-rw-r--r--libcxx/include/chrono12
-rw-r--r--libcxx/include/cmath6
-rw-r--r--libcxx/include/codecvt96
-rw-r--r--libcxx/include/condition_variable2
-rw-r--r--libcxx/include/deque18
-rw-r--r--libcxx/include/exception6
-rw-r--r--libcxx/include/experimental/functional6
-rw-r--r--libcxx/include/experimental/simd12
-rw-r--r--libcxx/include/ext/hash_map24
-rw-r--r--libcxx/include/ext/hash_set24
-rw-r--r--libcxx/include/format93
-rw-r--r--libcxx/include/forward_list42
-rw-r--r--libcxx/include/future8
-rw-r--r--libcxx/include/list16
-rw-r--r--libcxx/include/map64
-rw-r--r--libcxx/include/memory4
-rw-r--r--libcxx/include/module.modulemap.in41
-rw-r--r--libcxx/include/regex29
-rw-r--r--libcxx/include/scoped_allocator18
-rw-r--r--libcxx/include/shared_mutex4
-rw-r--r--libcxx/include/string_view4
-rw-r--r--libcxx/include/system_error4
-rw-r--r--libcxx/include/tuple16
-rw-r--r--libcxx/include/unordered_map52
-rw-r--r--libcxx/include/unordered_set40
-rw-r--r--libcxx/include/variant4
-rw-r--r--libcxx/include/vector68
-rw-r--r--libcxx/include/wchar.h8
173 files changed, 5406 insertions, 2625 deletions
diff --git a/libcxx/include/__algorithm/binary_search.h b/libcxx/include/__algorithm/binary_search.h
index 121a741d070b..a44007237850 100644
--- a/libcxx/include/__algorithm/binary_search.h
+++ b/libcxx/include/__algorithm/binary_search.h
@@ -25,20 +25,20 @@ template <class _ForwardIterator, class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
bool
-binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp)
{
using _Comp_ref = typename __comp_ref_type<_Compare>::type;
- __first = std::lower_bound<_ForwardIterator, _Tp, _Comp_ref>(__first, __last, __value_, __comp);
- return __first != __last && !__comp(__value_, *__first);
+ __first = std::lower_bound<_ForwardIterator, _Tp, _Comp_ref>(__first, __last, __value, __comp);
+ return __first != __last && !__comp(__value, *__first);
}
template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
bool
-binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
{
- return std::binary_search(__first, __last, __value_,
+ return std::binary_search(__first, __last, __value,
__less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
}
diff --git a/libcxx/include/__algorithm/count.h b/libcxx/include/__algorithm/count.h
index e18128cae8a8..5b546934038d 100644
--- a/libcxx/include/__algorithm/count.h
+++ b/libcxx/include/__algorithm/count.h
@@ -22,10 +22,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
typename iterator_traits<_InputIterator>::difference_type
- count(_InputIterator __first, _InputIterator __last, const _Tp& __value_) {
+ count(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
typename iterator_traits<_InputIterator>::difference_type __r(0);
for (; __first != __last; ++__first)
- if (*__first == __value_)
+ if (*__first == __value)
++__r;
return __r;
}
diff --git a/libcxx/include/__algorithm/equal_range.h b/libcxx/include/__algorithm/equal_range.h
index 2a07364bb66f..f30f55be64fc 100644
--- a/libcxx/include/__algorithm/equal_range.h
+++ b/libcxx/include/__algorithm/equal_range.h
@@ -30,7 +30,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Compare, class _ForwardIterator, class _Tp>
_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator>
-__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp)
{
typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
difference_type __len = _VSTD::distance(__first, __last);
@@ -39,12 +39,12 @@ __equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va
difference_type __l2 = _VSTD::__half_positive(__len);
_ForwardIterator __m = __first;
_VSTD::advance(__m, __l2);
- if (__comp(*__m, __value_))
+ if (__comp(*__m, __value))
{
__first = ++__m;
__len -= __l2 + 1;
}
- else if (__comp(__value_, *__m))
+ else if (__comp(__value, *__m))
{
__last = __m;
__len = __l2;
@@ -55,8 +55,8 @@ __equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va
_ForwardIterator __mp1 = __m;
return pair<_ForwardIterator, _ForwardIterator>
(
- _VSTD::__lower_bound_impl<_StdIterOps>(__first, __m, __value_, __comp, __proj),
- _VSTD::__upper_bound<_Compare>(++__mp1, __last, __value_, __comp)
+ _VSTD::__lower_bound_impl<_ClassicAlgPolicy>(__first, __m, __value, __comp, __proj),
+ _VSTD::__upper_bound<_Compare>(++__mp1, __last, __value, __comp)
);
}
}
@@ -67,19 +67,19 @@ template <class _ForwardIterator, class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
pair<_ForwardIterator, _ForwardIterator>
-equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp)
{
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
- return _VSTD::__equal_range<_Comp_ref>(__first, __last, __value_, __comp);
+ return _VSTD::__equal_range<_Comp_ref>(__first, __last, __value, __comp);
}
template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
pair<_ForwardIterator, _ForwardIterator>
-equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
{
- return _VSTD::equal_range(__first, __last, __value_,
+ return _VSTD::equal_range(__first, __last, __value,
__less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
}
diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h
index be5b4740a52a..ec9968fdb8b3 100644
--- a/libcxx/include/__algorithm/fill.h
+++ b/libcxx/include/__algorithm/fill.h
@@ -23,26 +23,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void
-__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag)
+__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, forward_iterator_tag)
{
for (; __first != __last; ++__first)
- *__first = __value_;
+ *__first = __value;
}
template <class _RandomAccessIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void
-__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag)
+__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, random_access_iterator_tag)
{
- _VSTD::fill_n(__first, __last - __first, __value_);
+ _VSTD::fill_n(__first, __last - __first, __value);
}
template <class _ForwardIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void
-fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
{
- _VSTD::__fill(__first, __last, __value_, typename iterator_traits<_ForwardIterator>::iterator_category());
+ _VSTD::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/fill_n.h b/libcxx/include/__algorithm/fill_n.h
index 590c8f38f3fd..7482a4188dd5 100644
--- a/libcxx/include/__algorithm/fill_n.h
+++ b/libcxx/include/__algorithm/fill_n.h
@@ -22,19 +22,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _OutputIterator, class _Size, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_OutputIterator
-__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
+__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value)
{
for (; __n > 0; ++__first, (void) --__n)
- *__first = __value_;
+ *__first = __value;
return __first;
}
template <class _OutputIterator, class _Size, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_OutputIterator
-fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
+fill_n(_OutputIterator __first, _Size __n, const _Tp& __value)
{
- return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value_);
+ return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value);
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h
index 641b85e2f645..ab37d81262f0 100644
--- a/libcxx/include/__algorithm/find.h
+++ b/libcxx/include/__algorithm/find.h
@@ -20,9 +20,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator
-find(_InputIterator __first, _InputIterator __last, const _Tp& __value_) {
+find(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
for (; __first != __last; ++__first)
- if (*__first == __value_)
+ if (*__first == __value)
break;
return __first;
}
diff --git a/libcxx/include/__algorithm/find_end.h b/libcxx/include/__algorithm/find_end.h
index 0220c0939711..65e9f29b1c1f 100644
--- a/libcxx/include/__algorithm/find_end.h
+++ b/libcxx/include/__algorithm/find_end.h
@@ -11,8 +11,16 @@
#define _LIBCPP___ALGORITHM_FIND_END_OF_H
#include <__algorithm/comp.h>
+#include <__algorithm/iterator_operations.h>
+#include <__algorithm/search.h>
#include <__config>
+#include <__functional/identity.h>
+#include <__iterator/advance.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__iterator/reverse_iterator.h>
+#include <__utility/pair.h>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -20,35 +28,52 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
-_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
- _ForwardIterator2 __first2, _ForwardIterator2 __last2,
- _BinaryPredicate __pred, forward_iterator_tag,
- forward_iterator_tag) {
+template <
+ class _AlgPolicy,
+ class _Iter1,
+ class _Sent1,
+ class _Iter2,
+ class _Sent2,
+ class _Pred,
+ class _Proj1,
+ class _Proj2>
+_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_AFTER_CXX11 pair<_Iter1, _Iter1> __find_end_impl(
+ _Iter1 __first1,
+ _Sent1 __last1,
+ _Iter2 __first2,
+ _Sent2 __last2,
+ _Pred& __pred,
+ _Proj1& __proj1,
+ _Proj2& __proj2,
+ forward_iterator_tag,
+ forward_iterator_tag) {
// modeled after search algorithm
- _ForwardIterator1 __r = __last1; // __last1 is the "default" answer
+ _Iter1 __match_first = _IterOps<_AlgPolicy>::next(__first1, __last1); // __last1 is the "default" answer
+ _Iter1 __match_last = __match_first;
if (__first2 == __last2)
- return __r;
+ return pair<_Iter1, _Iter1>(__match_last, __match_last);
while (true) {
while (true) {
- if (__first1 == __last1) // if source exhausted return last correct answer
- return __r; // (or __last1 if never found)
- if (__pred(*__first1, *__first2))
+ if (__first1 == __last1) // if source exhausted return last correct answer (or __last1 if never found)
+ return pair<_Iter1, _Iter1>(__match_first, __match_last);
+ if (std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
break;
++__first1;
}
// *__first1 matches *__first2, now match elements after here
- _ForwardIterator1 __m1 = __first1;
- _ForwardIterator2 __m2 = __first2;
+ _Iter1 __m1 = __first1;
+ _Iter2 __m2 = __first2;
while (true) {
if (++__m2 == __last2) { // Pattern exhaused, record answer and search for another one
- __r = __first1;
+ __match_first = __first1;
+ __match_last = ++__m1;
++__first1;
break;
}
if (++__m1 == __last1) // Source exhausted, return last answer
- return __r;
- if (!__pred(*__m1, *__m2)) // mismatch, restart with a new __first
+ return pair<_Iter1, _Iter1>(__match_first, __match_last);
+ // mismatch, restart with a new __first
+ if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2)))
{
++__first1;
break;
@@ -57,33 +82,52 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 __find_end(_ForwardIterator1 __f
}
}
-template <class _BinaryPredicate, class _BidirectionalIterator1, class _BidirectionalIterator2>
-_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1 __find_end(
- _BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, _BidirectionalIterator2 __first2,
- _BidirectionalIterator2 __last2, _BinaryPredicate __pred, bidirectional_iterator_tag, bidirectional_iterator_tag) {
+template <
+ class _IterOps,
+ class _Pred,
+ class _Iter1,
+ class _Sent1,
+ class _Iter2,
+ class _Sent2,
+ class _Proj1,
+ class _Proj2>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _Iter1 __find_end(
+ _Iter1 __first1,
+ _Sent1 __sent1,
+ _Iter2 __first2,
+ _Sent2 __sent2,
+ _Pred& __pred,
+ _Proj1& __proj1,
+ _Proj2& __proj2,
+ bidirectional_iterator_tag,
+ bidirectional_iterator_tag) {
+ auto __last1 = _IterOps::next(__first1, __sent1);
+ auto __last2 = _IterOps::next(__first2, __sent2);
// modeled after search algorithm (in reverse)
if (__first2 == __last2)
return __last1; // Everything matches an empty sequence
- _BidirectionalIterator1 __l1 = __last1;
- _BidirectionalIterator2 __l2 = __last2;
+ _Iter1 __l1 = __last1;
+ _Iter2 __l2 = __last2;
--__l2;
while (true) {
// Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks
while (true) {
if (__first1 == __l1) // return __last1 if no element matches *__first2
return __last1;
- if (__pred(*--__l1, *__l2))
+ if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
break;
}
// *__l1 matches *__l2, now match elements before here
- _BidirectionalIterator1 __m1 = __l1;
- _BidirectionalIterator2 __m2 = __l2;
+ _Iter1 __m1 = __l1;
+ _Iter2 __m2 = __l2;
while (true) {
if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern)
return __m1;
if (__m1 == __first1) // Otherwise if source exhaused, pattern not found
return __last1;
- if (!__pred(*--__m1, *--__m2)) // if there is a mismatch, restart with a new __l1
+
+ // if there is a mismatch, restart with a new __l1
+ if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2)))
{
break;
} // else there is a match, check next elements
@@ -91,37 +135,53 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1 __find_end(
}
}
-template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 __find_end(
- _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
- _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag) {
- typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1;
- typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2;
+template <
+ class _AlgPolicy,
+ class _Pred,
+ class _Iter1,
+ class _Sent1,
+ class _Iter2,
+ class _Sent2,
+ class _Proj1,
+ class _Proj2>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _Iter1 __find_end(
+ _Iter1 __first1,
+ _Sent1 __sent1,
+ _Iter2 __first2,
+ _Sent2 __sent2,
+ _Pred& __pred,
+ _Proj1& __proj1,
+ _Proj2& __proj2,
+ random_access_iterator_tag,
+ random_access_iterator_tag) {
+ typedef typename iterator_traits<_Iter1>::difference_type _D1;
+ auto __last1 = _IterOps<_AlgPolicy>::next(__first1, __sent1);
+ auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __sent2);
// Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
- _D2 __len2 = __last2 - __first2;
+ auto __len2 = __last2 - __first2;
if (__len2 == 0)
return __last1;
- _D1 __len1 = __last1 - __first1;
+ auto __len1 = __last1 - __first1;
if (__len1 < __len2)
return __last1;
- const _RandomAccessIterator1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here
- _RandomAccessIterator1 __l1 = __last1;
- _RandomAccessIterator2 __l2 = __last2;
+ const _Iter1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here
+ _Iter1 __l1 = __last1;
+ _Iter2 __l2 = __last2;
--__l2;
while (true) {
while (true) {
if (__s == __l1)
return __last1;
- if (__pred(*--__l1, *__l2))
+ if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
break;
}
- _RandomAccessIterator1 __m1 = __l1;
- _RandomAccessIterator2 __m2 = __l2;
+ _Iter1 __m1 = __l1;
+ _Iter2 __m2 = __l2;
while (true) {
if (__m2 == __first2)
return __m1;
// no need to check range on __m1 because __s guarantees we have enough source
- if (!__pred(*--__m1, *--__m2)) {
+ if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(*--__m2))) {
break;
}
}
@@ -129,20 +189,39 @@ _LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 __find_end(
}
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
-find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2,
- _BinaryPredicate __pred) {
- return _VSTD::__find_end<_BinaryPredicate&>(
- __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_ForwardIterator1>::iterator_category(),
- typename iterator_traits<_ForwardIterator2>::iterator_category());
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+_ForwardIterator1 __find_end_classic(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+ _BinaryPredicate& __pred) {
+ auto __proj = __identity();
+ return std::__find_end_impl<_ClassicAlgPolicy>(
+ __first1,
+ __last1,
+ __first2,
+ __last2,
+ __pred,
+ __proj,
+ __proj,
+ typename iterator_traits<_ForwardIterator1>::iterator_category(),
+ typename iterator_traits<_ForwardIterator2>::iterator_category())
+ .first;
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+ _BinaryPredicate __pred) {
+ return std::__find_end_classic(__first1, __last1, __first2, __last2, __pred);
}
template <class _ForwardIterator1, class _ForwardIterator2>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
-find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
- typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
- typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
- return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
+ using __v1 = typename iterator_traits<_ForwardIterator1>::value_type;
+ using __v2 = typename iterator_traits<_ForwardIterator2>::value_type;
+ return std::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/iterator_operations.h b/libcxx/include/__algorithm/iterator_operations.h
index c02f9bf649df..eb627e1ace7a 100644
--- a/libcxx/include/__algorithm/iterator_operations.h
+++ b/libcxx/include/__algorithm/iterator_operations.h
@@ -6,13 +6,20 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP___ALGORIHTM_ITERATOR_OPERATIONS_H
-#define _LIBCPP___ALGORIHTM_ITERATOR_OPERATIONS_H
+#ifndef _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H
+#define _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H
+#include <__algorithm/iter_swap.h>
#include <__config>
#include <__iterator/advance.h>
#include <__iterator/distance.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -20,28 +27,69 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _AlgPolicy> struct _IterOps;
+
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
-struct _RangesIterOps {
+struct _RangeAlgPolicy {};
+
+template <>
+struct _IterOps<_RangeAlgPolicy> {
static constexpr auto advance = ranges::advance;
static constexpr auto distance = ranges::distance;
+ static constexpr auto __iter_move = ranges::iter_move;
+ static constexpr auto iter_swap = ranges::iter_swap;
+ static constexpr auto next = ranges::next;
+ static constexpr auto __advance_to = ranges::advance;
};
#endif
-struct _StdIterOps {
+struct _ClassicAlgPolicy {};
+
+template <>
+struct _IterOps<_ClassicAlgPolicy> {
+
+ // advance
+ template <class _Iter, class _Distance>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+ static void advance(_Iter& __iter, _Distance __count) {
+ std::advance(__iter, __count);
+ }
+
+ // distance
+ template <class _Iter>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+ static typename iterator_traits<_Iter>::difference_type distance(_Iter __first, _Iter __last) {
+ return std::distance(__first, __last);
+ }
+
+ // iter_move
+ template <class _Iter>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+ // Declaring the return type is necessary for the C++03 mode (which doesn't support placeholder return types).
+ static typename iterator_traits<__uncvref_t<_Iter> >::value_type&& __iter_move(_Iter&& __i) {
+ return std::move(*std::forward<_Iter>(__i));
+ }
- template <class _Iterator, class _Distance>
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 void advance(_Iterator& __iter, _Distance __count) {
- return std::advance(__iter, __count);
+ // iter_swap
+ template <class _Iter1, class _Iter2>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+ static void iter_swap(_Iter1&& __a, _Iter2&& __b) {
+ std::iter_swap(std::forward<_Iter1>(__a), std::forward<_Iter2>(__b));
}
+ // next
template <class _Iterator>
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11
- typename iterator_traits<_Iterator>::difference_type distance(_Iterator __first, _Iterator __last) {
- return std::distance(__first, __last);
+ _Iterator next(_Iterator, _Iterator __last) {
+ return __last;
}
+ template <class _Iter>
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 void __advance_to(_Iter& __first, _Iter __last) {
+ __first = __last;
+ }
};
_LIBCPP_END_NAMESPACE_STD
-#endif // _LIBCPP___ALGORIHTM_ITERATOR_OPERATIONS_H
+#endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H
diff --git a/libcxx/include/__algorithm/lower_bound.h b/libcxx/include/__algorithm/lower_bound.h
index fbcd5c7e908a..2c92f715265a 100644
--- a/libcxx/include/__algorithm/lower_bound.h
+++ b/libcxx/include/__algorithm/lower_bound.h
@@ -19,6 +19,7 @@
#include <__iterator/distance.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_callable.h>
+#include <__type_traits/remove_reference.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -27,15 +28,15 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _IterOps, class _Iter, class _Sent, class _Type, class _Proj, class _Comp>
+template <class _AlgPolicy, class _Iter, class _Sent, class _Type, class _Proj, class _Comp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
_Iter __lower_bound_impl(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
- auto __len = _IterOps::distance(__first, __last);
+ auto __len = _IterOps<_AlgPolicy>::distance(__first, __last);
while (__len != 0) {
auto __l2 = std::__half_positive(__len);
_Iter __m = __first;
- _IterOps::advance(__m, __l2);
+ _IterOps<_AlgPolicy>::advance(__m, __l2);
if (std::__invoke(__comp, std::__invoke(__proj, *__m), __value)) {
__first = ++__m;
__len -= __l2 + 1;
@@ -48,17 +49,17 @@ _Iter __lower_bound_impl(_Iter __first, _Sent __last, const _Type& __value, _Com
template <class _ForwardIterator, class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
-_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) {
+_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) {
static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value,
"The comparator has to be callable");
auto __proj = std::__identity();
- return std::__lower_bound_impl<_StdIterOps>(__first, __last, __value_, __comp, __proj);
+ return std::__lower_bound_impl<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj);
}
template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
-_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) {
- return std::lower_bound(__first, __last, __value_,
+_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+ return std::lower_bound(__first, __last, __value,
__less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
}
diff --git a/libcxx/include/__algorithm/make_heap.h b/libcxx/include/__algorithm/make_heap.h
index acac0aabf1e4..bc39d82bf916 100644
--- a/libcxx/include/__algorithm/make_heap.h
+++ b/libcxx/include/__algorithm/make_heap.h
@@ -14,6 +14,7 @@
#include <__algorithm/sift_down.h>
#include <__config>
#include <__iterator/iterator_traits.h>
+#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -22,36 +23,32 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Compare, class _RandomAccessIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 void
-__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
- typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
- difference_type __n = __last - __first;
- if (__n > 1)
- {
- // start from the first parent, there is no need to consider children
- for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start)
- {
- _VSTD::__sift_down<_Compare>(__first, __comp, __n, __first + __start);
- }
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
+ using _CompRef = typename __comp_ref_type<_Compare>::type;
+ _CompRef __comp_ref = __comp;
+
+ using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
+ difference_type __n = __last - __first;
+ if (__n > 1) {
+ // start from the first parent, there is no need to consider children
+ for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) {
+ std::__sift_down<_CompRef>(__first, __comp_ref, __n, __first + __start);
}
+ }
}
template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-void
-make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
- typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
- _VSTD::__make_heap<_Comp_ref>(__first, __last, __comp);
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+ std::__make_heap(std::move(__first), std::move(__last), __comp);
}
template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-void
-make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
- _VSTD::make_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
+ std::make_heap(std::move(__first), std::move(__last),
+ __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/make_projected.h b/libcxx/include/__algorithm/make_projected.h
index 8141c4ed176f..6d8ebfd3d90e 100644
--- a/libcxx/include/__algorithm/make_projected.h
+++ b/libcxx/include/__algorithm/make_projected.h
@@ -13,6 +13,8 @@
#include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_member_pointer.h>
#include <__utility/forward.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -28,7 +30,7 @@ namespace ranges {
template <class _Comp, class _Proj>
_LIBCPP_HIDE_FROM_ABI constexpr static
decltype(auto) __make_projected_comp(_Comp& __comp, _Proj& __proj) {
- if constexpr (same_as<_Proj, identity>) {
+ if constexpr (same_as<decay_t<_Proj>, identity> && !is_member_pointer_v<decay_t<_Comp>>) {
// Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable
// optimizations that rely on the type of the comparator.
return __comp;
@@ -42,6 +44,24 @@ decltype(auto) __make_projected_comp(_Comp& __comp, _Proj& __proj) {
}
}
+template <class _Comp, class _Proj1, class _Proj2>
+_LIBCPP_HIDE_FROM_ABI constexpr static
+decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
+ if constexpr (same_as<decay_t<_Proj1>, identity> && same_as<decay_t<_Proj2>, identity> &&
+ !is_member_pointer_v<decay_t<_Comp>>) {
+ // Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable
+ // optimizations that rely on the type of the comparator.
+ return __comp;
+
+ } else {
+ return [&](auto&& __lhs, auto&& __rhs) {
+ return std::invoke(__comp,
+ std::invoke(__proj1, std::forward<decltype(__lhs)>(__lhs)),
+ std::invoke(__proj2, std::forward<decltype(__rhs)>(__rhs)));
+ };
+ }
+}
+
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/minmax_element.h b/libcxx/include/__algorithm/minmax_element.h
index fe5f20bf1c7f..cf67184e0b4c 100644
--- a/libcxx/include/__algorithm/minmax_element.h
+++ b/libcxx/include/__algorithm/minmax_element.h
@@ -24,17 +24,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Comp, class _Proj>
class _MinmaxElementLessFunc {
- _Comp& __comp;
- _Proj& __proj;
+ _Comp& __comp_;
+ _Proj& __proj_;
public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
- _MinmaxElementLessFunc(_Comp& __comp_, _Proj& __proj_) : __comp(__comp_), __proj(__proj_) {}
+ _MinmaxElementLessFunc(_Comp& __comp, _Proj& __proj) : __comp_(__comp), __proj_(__proj) {}
template <class _Iter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
bool operator()(_Iter& __it1, _Iter& __it2) {
- return std::__invoke(__comp, std::__invoke(__proj, *__it1), std::__invoke(__proj, *__it2));
+ return std::__invoke(__comp_, std::__invoke(__proj_, *__it1), std::__invoke(__proj_, *__it2));
}
};
diff --git a/libcxx/include/__algorithm/nth_element.h b/libcxx/include/__algorithm/nth_element.h
index 60b9280f75f0..c7cdef5be817 100644
--- a/libcxx/include/__algorithm/nth_element.h
+++ b/libcxx/include/__algorithm/nth_element.h
@@ -14,13 +14,11 @@
#include <__algorithm/sort.h>
#include <__config>
#include <__debug>
+#include <__debug_utils/randomize_range.h>
#include <__iterator/iterator_traits.h>
+#include <__utility/move.h>
#include <__utility/swap.h>
-#if defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY)
-# include <__algorithm/shuffle.h>
-#endif
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
@@ -223,25 +221,35 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando
}
template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-void
-nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
-{
- _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __last);
- typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
- _VSTD::__nth_element<_Comp_ref>(__first, __nth, __last, __comp);
- _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __nth);
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void __nth_element_impl(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last,
+ _Compare& __comp) {
+ if (__nth == __last)
+ return;
+
+ std::__debug_randomize_range(__first, __last);
+
+ using _Comp_ref = typename __comp_ref_type<_Compare>::type;
+ std::__nth_element<_Comp_ref>(__first, __nth, __last, __comp);
+
+ std::__debug_randomize_range(__first, __nth);
if (__nth != __last) {
- _LIBCPP_DEBUG_RANDOMIZE_RANGE(++__nth, __last);
+ std::__debug_randomize_range(++__nth, __last);
}
}
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last,
+ _Compare __comp) {
+ std::__nth_element_impl(std::move(__first), std::move(__nth), std::move(__last), __comp);
+}
+
template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-void
-nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last)
-{
- _VSTD::nth_element(__first, __nth, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) {
+ std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<typename
+ iterator_traits<_RandomAccessIterator>::value_type>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/partial_sort.h b/libcxx/include/__algorithm/partial_sort.h
index 3870c0cc9335..e008c0c99679 100644
--- a/libcxx/include/__algorithm/partial_sort.h
+++ b/libcxx/include/__algorithm/partial_sort.h
@@ -16,13 +16,10 @@
#include <__algorithm/sort_heap.h>
#include <__config>
#include <__debug>
+#include <__debug_utils/randomize_range.h>
#include <__iterator/iterator_traits.h>
#include <__utility/swap.h>
-#if defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY)
-# include <__algorithm/shuffle.h>
-#endif
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
@@ -55,10 +52,10 @@ void
partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
_Compare __comp)
{
- _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __last);
+ std::__debug_randomize_range(__first, __last);
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
_VSTD::__partial_sort<_Comp_ref>(__first, __middle, __last, __comp);
- _LIBCPP_DEBUG_RANDOMIZE_RANGE(__middle, __last);
+ std::__debug_randomize_range(__middle, __last);
}
template <class _RandomAccessIterator>
diff --git a/libcxx/include/__algorithm/pop_heap.h b/libcxx/include/__algorithm/pop_heap.h
index 2932a5e31dbc..cadda81f6c88 100644
--- a/libcxx/include/__algorithm/pop_heap.h
+++ b/libcxx/include/__algorithm/pop_heap.h
@@ -13,6 +13,7 @@
#include <__algorithm/comp_ref_type.h>
#include <__algorithm/push_heap.h>
#include <__algorithm/sift_down.h>
+#include <__assert>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__utility/move.h>
@@ -24,44 +25,43 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Compare, class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-void
-__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
- typename iterator_traits<_RandomAccessIterator>::difference_type __len)
-{
- using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp,
+ typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
+ _LIBCPP_ASSERT(__len > 0, "The heap given to pop_heap must be non-empty");
- if (__len > 1)
- {
- value_type __top = std::move(*__first); // create a hole at __first
- _RandomAccessIterator __hole = std::__floyd_sift_down<_Compare>(__first, __comp, __len);
- --__last;
- if (__hole == __last) {
- *__hole = std::move(__top);
- } else {
- *__hole = std::move(*__last);
- ++__hole;
- *__last = std::move(__top);
- std::__sift_up<_Compare>(__first, __hole, __comp, __hole - __first);
- }
+ using _CompRef = typename __comp_ref_type<_Compare>::type;
+ _CompRef __comp_ref = __comp;
+
+ using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
+ if (__len > 1) {
+ value_type __top = std::move(*__first); // create a hole at __first
+ _RandomAccessIterator __hole = std::__floyd_sift_down<_CompRef>(__first, __comp_ref, __len);
+ --__last;
+
+ if (__hole == __last) {
+ *__hole = std::move(__top);
+ } else {
+ *__hole = std::move(*__last);
+ ++__hole;
+ *__last = std::move(__top);
+ std::__sift_up<_CompRef>(__first, __hole, __comp_ref, __hole - __first);
}
+ }
}
template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-void
-pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
- typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
- _VSTD::__pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first);
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+ typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first;
+ std::__pop_heap(std::move(__first), std::move(__last), __comp, __len);
}
template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-void
-pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
- _VSTD::pop_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
+ std::pop_heap(std::move(__first), std::move(__last),
+ __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/push_heap.h b/libcxx/include/__algorithm/push_heap.h
index 66973e082f14..1e3eec373d4f 100644
--- a/libcxx/include/__algorithm/push_heap.h
+++ b/libcxx/include/__algorithm/push_heap.h
@@ -22,47 +22,50 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Compare, class _RandomAccessIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 void
-__sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
- typename iterator_traits<_RandomAccessIterator>::difference_type __len)
-{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
- if (__len > 1)
- {
- __len = (__len - 2) / 2;
- _RandomAccessIterator __ptr = __first + __len;
- if (__comp(*__ptr, *--__last))
- {
- value_type __t(_VSTD::move(*__last));
- do
- {
- *__last = _VSTD::move(*__ptr);
- __last = __ptr;
- if (__len == 0)
- break;
- __len = (__len - 1) / 2;
- __ptr = __first + __len;
- } while (__comp(*__ptr, __t));
- *__last = _VSTD::move(__t);
- }
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
+ typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
+ using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
+
+ if (__len > 1) {
+ __len = (__len - 2) / 2;
+ _RandomAccessIterator __ptr = __first + __len;
+
+ if (__comp(*__ptr, *--__last)) {
+ value_type __t(std::move(*__last));
+ do {
+ *__last = std::move(*__ptr);
+ __last = __ptr;
+ if (__len == 0)
+ break;
+ __len = (__len - 1) / 2;
+ __ptr = __first + __len;
+ } while (__comp(*__ptr, __t));
+
+ *__last = std::move(__t);
}
+ }
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+void __push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
+ using _CompRef = typename __comp_ref_type<_Compare>::type;
+ typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first;
+ std::__sift_up<_CompRef>(std::move(__first), std::move(__last), __comp, __len);
}
template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-void
-push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
- typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
- _VSTD::__sift_up<_Comp_ref>(__first, __last, __comp, __last - __first);
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+ std::__push_heap(std::move(__first), std::move(__last), __comp);
}
template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-void
-push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
- _VSTD::push_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
+ std::push_heap(std::move(__first), std::move(__last),
+ __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/ranges_binary_search.h b/libcxx/include/__algorithm/ranges_binary_search.h
index 68359fb1388f..6da68834aa3b 100644
--- a/libcxx/include/__algorithm/ranges_binary_search.h
+++ b/libcxx/include/__algorithm/ranges_binary_search.h
@@ -35,7 +35,7 @@ struct __fn {
indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
_LIBCPP_HIDE_FROM_ABI constexpr
bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
- auto __ret = std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp, __proj);
+ auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first));
}
@@ -45,7 +45,7 @@ struct __fn {
bool operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
auto __first = ranges::begin(__r);
auto __last = ranges::end(__r);
- auto __ret = std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp, __proj);
+ auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first));
}
};
diff --git a/libcxx/include/__algorithm/ranges_equal_range.h b/libcxx/include/__algorithm/ranges_equal_range.h
new file mode 100644
index 000000000000..28d721530bda
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_equal_range.h
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM __project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H
+#define _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H
+
+#include <__algorithm/equal_range.h>
+#include <__algorithm/make_projected.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__ranges/subrange.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __equal_range {
+
+struct __fn {
+
+ template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Tp, class _Proj = identity,
+ indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Tp& __value, _Comp __comp = {},
+ _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__value; (void)__comp; (void)__proj;
+ return {};
+ }
+
+ template <forward_range _Range, class _Tp, class _Proj = identity,
+ indirect_strict_weak_order<const _Tp*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Tp& __value, _Comp __comp = {},
+ _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__value; (void)__comp; (void)__proj;
+ return {};
+ }
+
+};
+
+} // namespace __equal_range
+
+inline namespace __cpo {
+ inline constexpr auto equal_range = __equal_range::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H
diff --git a/libcxx/include/__algorithm/ranges_find_end.h b/libcxx/include/__algorithm/ranges_find_end.h
new file mode 100644
index 000000000000..fec709e79f5a
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_find_end.h
@@ -0,0 +1,113 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_END_H
+#define _LIBCPP___ALGORITHM_RANGES_FIND_END_H
+
+#include <__algorithm/find_end.h>
+#include <__algorithm/iterator_operations.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__iterator/iterator_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/subrange.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Iter>
+consteval auto __get_iterator_concept() {
+ if constexpr (contiguous_iterator<_Iter>)
+ return contiguous_iterator_tag();
+ else if constexpr (random_access_iterator<_Iter>)
+ return random_access_iterator_tag();
+ else if constexpr (bidirectional_iterator<_Iter>)
+ return bidirectional_iterator_tag();
+ else if constexpr (forward_iterator<_Iter>)
+ return forward_iterator_tag();
+ else if constexpr (input_iterator<_Iter>)
+ return input_iterator_tag();
+}
+
+template <class _Iter>
+using __iterator_concept = decltype(__get_iterator_concept<_Iter>());
+
+namespace ranges {
+namespace __find_end {
+struct __fn {
+ template <forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
+ forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
+ class _Pred = ranges::equal_to,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Pred __pred = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ auto __ret = std::__find_end_impl<_RangeAlgPolicy>(
+ __first1,
+ __last1,
+ __first2,
+ __last2,
+ __pred,
+ __proj1,
+ __proj2,
+ __iterator_concept<_Iter1>(),
+ __iterator_concept<_Iter2>());
+ return {__ret.first, __ret.second};
+ }
+
+ template <forward_range _Range1,
+ forward_range _Range2,
+ class _Pred = ranges::equal_to,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_subrange_t<_Range1> operator()(_Range1&& __range1,
+ _Range2&& __range2,
+ _Pred __pred = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ auto __ret = std::__find_end_impl<_RangeAlgPolicy>(
+ ranges::begin(__range1),
+ ranges::end(__range1),
+ ranges::begin(__range2),
+ ranges::end(__range2),
+ __pred,
+ __proj1,
+ __proj2,
+ __iterator_concept<iterator_t<_Range1>>(),
+ __iterator_concept<iterator_t<_Range2>>());
+ return {__ret.first, __ret.second};
+ }
+};
+} // namespace __find_end
+
+inline namespace __cpo {
+ inline constexpr auto find_end = __find_end::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_FIND_END_H
diff --git a/libcxx/include/__algorithm/ranges_generate.h b/libcxx/include/__algorithm/ranges_generate.h
new file mode 100644
index 000000000000..c23645e6d906
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_generate.h
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_GENERATE_H
+#define _LIBCPP___ALGORITHM_RANGES_GENERATE_H
+
+#include <__algorithm/generate.h>
+#include <__algorithm/make_projected.h>
+#include <__concepts/constructible.h>
+#include <__concepts/invocable.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __generate {
+
+struct __fn {
+
+ template <input_or_output_iterator _OutIter, sentinel_for<_OutIter> _Sent, copy_constructible _Func>
+ requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _OutIter operator()(_OutIter __first, _Sent __last, _Func __gen) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__gen;
+ return {};
+ }
+
+ template <class _Range, copy_constructible _Func>
+ requires invocable<_Func&> && output_range<_Range, invoke_result_t<_Func&>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __range, _Func __gen) const {
+ // TODO: implement
+ (void)__range; (void)__gen;
+ return {};
+ }
+
+};
+
+} // namespace __generate
+
+inline namespace __cpo {
+ inline constexpr auto generate = __generate::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_H
diff --git a/libcxx/include/__algorithm/ranges_generate_n.h b/libcxx/include/__algorithm/ranges_generate_n.h
new file mode 100644
index 000000000000..bcf50e025ecc
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_generate_n.h
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H
+#define _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H
+
+#include <__algorithm/generate_n.h>
+#include <__algorithm/make_projected.h>
+#include <__concepts/constructible.h>
+#include <__concepts/invocable.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __generate_n {
+
+struct __fn {
+
+ template <input_or_output_iterator _OutIter, copy_constructible _Func>
+ requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _OutIter operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const {
+ // TODO: implement
+ (void)__first; (void)__n; (void)__gen;
+ return {};
+ }
+
+};
+
+} // namespace __generate_n
+
+inline namespace __cpo {
+ inline constexpr auto generate_n = __generate_n::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H
diff --git a/libcxx/include/__algorithm/ranges_includes.h b/libcxx/include/__algorithm/ranges_includes.h
new file mode 100644
index 000000000000..19c17870ed6f
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_includes.h
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_INCLUDES_H
+#define _LIBCPP___ALGORITHM_RANGES_INCLUDES_H
+
+#include <__algorithm/make_projected.h>
+#include <__algorithm/includes.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __includes {
+
+struct __fn {
+
+ template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1, input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
+ class _Proj1 = identity, class _Proj2 = identity,
+ indirect_strict_weak_order<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Comp __comp = {},
+ _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+ // TODO: implement
+ (void)__first1; (void)__last1; (void)__first2; (void)__last2; (void)__comp; (void)__proj1; (void)__proj2;
+ return {};
+ }
+
+ template <input_range _Range1, input_range _Range2, class _Proj1 = identity, class _Proj2 = identity,
+ indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>,
+ projected<iterator_t<_Range2>, _Proj2>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Range1&& __range1, _Range2&& __range2, _Comp __comp = {},
+ _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+ // TODO: implement
+ (void)__range1; (void)__range2; (void)__comp; (void)__proj1; (void)__proj2;
+ return {};
+ }
+
+};
+
+} // namespace __includes
+
+inline namespace __cpo {
+ inline constexpr auto includes = __includes::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_INCLUDES_H
diff --git a/libcxx/include/__algorithm/ranges_inplace_merge.h b/libcxx/include/__algorithm/ranges_inplace_merge.h
new file mode 100644
index 000000000000..a0867e486c3a
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_inplace_merge.h
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H
+#define _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H
+
+#include <__algorithm/inplace_merge.h>
+#include <__algorithm/make_projected.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__iterator/sortable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __inplace_merge {
+
+struct __fn {
+
+ template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<_Iter, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI
+ _Iter operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__middle; (void)__last; (void)__comp; (void)__proj;
+ return {};
+ }
+
+ template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<iterator_t<_Range>, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI
+ borrowed_iterator_t<_Range> operator()(_Range&& __range, iterator_t<_Range> __middle,
+ _Comp __comp = {}, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__middle; (void)__comp; (void)__proj;
+ return {};
+ }
+
+};
+
+} // namespace __inplace_merge
+
+inline namespace __cpo {
+ inline constexpr auto inplace_merge = __inplace_merge::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H
diff --git a/libcxx/include/__algorithm/ranges_is_heap.h b/libcxx/include/__algorithm/ranges_is_heap.h
new file mode 100644
index 000000000000..0f10fa4dcec9
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_is_heap.h
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H
+#define _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H
+
+#include <__algorithm/is_heap.h>
+#include <__algorithm/make_projected.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __is_heap {
+
+struct __fn {
+
+ template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+ indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__comp; (void)__proj;
+ return {};
+ }
+
+ template <random_access_range _Range, class _Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__comp; (void)__proj;
+ return {};
+ }
+};
+
+} // namespace __is_heap
+
+inline namespace __cpo {
+ inline constexpr auto is_heap = __is_heap::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H
diff --git a/libcxx/include/__algorithm/ranges_is_heap_until.h b/libcxx/include/__algorithm/ranges_is_heap_until.h
new file mode 100644
index 000000000000..ad021d6f2525
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_is_heap_until.h
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H
+#define _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H
+
+#include <__algorithm/is_heap_until.h>
+#include <__algorithm/make_projected.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __is_heap_until {
+
+struct __fn {
+
+ template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+ indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__comp; (void)__proj;
+ return {};
+ }
+
+ template <random_access_range _Range, class _Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__comp; (void)__proj;
+ return {};
+ }
+
+};
+
+} // namespace __is_heap_until
+
+inline namespace __cpo {
+ inline constexpr auto is_heap_until = __is_heap_until::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H
diff --git a/libcxx/include/__algorithm/ranges_lower_bound.h b/libcxx/include/__algorithm/ranges_lower_bound.h
index a73470465cfd..1a9ae204a1ee 100644
--- a/libcxx/include/__algorithm/ranges_lower_bound.h
+++ b/libcxx/include/__algorithm/ranges_lower_bound.h
@@ -39,7 +39,7 @@ struct __fn {
indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
_LIBCPP_HIDE_FROM_ABI constexpr
_Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
- return std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp, __proj);
+ return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
}
template <forward_range _Range, class _Type, class _Proj = identity,
@@ -49,7 +49,7 @@ struct __fn {
const _Type& __value,
_Comp __comp = {},
_Proj __proj = {}) const {
- return std::__lower_bound_impl<_RangesIterOps>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj);
+ return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj);
}
};
} // namespace __lower_bound
diff --git a/libcxx/include/__algorithm/ranges_make_heap.h b/libcxx/include/__algorithm/ranges_make_heap.h
new file mode 100644
index 000000000000..fd488dc11a4b
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_make_heap.h
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H
+#define _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H
+
+#include <__algorithm/make_heap.h>
+#include <__algorithm/make_projected.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__iterator/projected.h>
+#include <__iterator/sortable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __make_heap {
+
+struct __fn {
+ template <class _Iter, class _Sent, class _Comp, class _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ _Iter __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+ auto __last_iter = ranges::next(__first, __last);
+
+ auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ std::__make_heap(std::move(__first), __last_iter, __projected_comp);
+
+ return __last_iter;
+ }
+
+ template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<_Iter, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ return __make_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
+ }
+
+ template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<iterator_t<_Range>, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+ return __make_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
+ }
+};
+
+} // namespace __make_heap
+
+inline namespace __cpo {
+ inline constexpr auto make_heap = __make_heap::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H
diff --git a/libcxx/include/__algorithm/ranges_merge.h b/libcxx/include/__algorithm/ranges_merge.h
new file mode 100644
index 000000000000..c73e09e94ccc
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_merge.h
@@ -0,0 +1,142 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_MERGE_H
+#define _LIBCPP___ALGORITHM_RANGES_MERGE_H
+
+#include <__algorithm/in_in_out_result.h>
+#include <__algorithm/ranges_copy.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/mergeable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter1, class _InIter2, class _OutIter>
+using merge_result = in_in_out_result<_InIter1, _InIter2, _OutIter>;
+
+namespace __merge {
+
+template <
+ class _InIter1,
+ class _Sent1,
+ class _InIter2,
+ class _Sent2,
+ class _OutIter,
+ class _Comp,
+ class _Proj1,
+ class _Proj2>
+_LIBCPP_HIDE_FROM_ABI constexpr merge_result<__uncvref_t<_InIter1>, __uncvref_t<_InIter2>, __uncvref_t<_OutIter>>
+__merge_impl(
+ _InIter1&& __first1,
+ _Sent1&& __last1,
+ _InIter2&& __first2,
+ _Sent2&& __last2,
+ _OutIter&& __result,
+ _Comp&& __comp,
+ _Proj1&& __proj1,
+ _Proj2&& __proj2) {
+ for (; __first1 != __last1 && __first2 != __last2; ++__result) {
+ if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1))) {
+ *__result = *__first2;
+ ++__first2;
+ } else {
+ *__result = *__first1;
+ ++__first1;
+ }
+ }
+ auto __ret1 = ranges::copy(std::move(__first1), std::move(__last1), std::move(__result));
+ auto __ret2 = ranges::copy(std::move(__first2), std::move(__last2), std::move(__ret1.out));
+ return {std::move(__ret1.in), std::move(__ret2.in), std::move(__ret2.out)};
+}
+
+struct __fn {
+ template <
+ input_iterator _InIter1,
+ sentinel_for<_InIter1> _Sent1,
+ input_iterator _InIter2,
+ sentinel_for<_InIter2> _Sent2,
+ weakly_incrementable _OutIter,
+ class _Comp = less,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr merge_result<_InIter1, _InIter2, _OutIter> operator()(
+ _InIter1 __first1,
+ _Sent1 __last1,
+ _InIter2 __first2,
+ _Sent2 __last2,
+ _OutIter __result,
+ _Comp __comp = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ return __merge::__merge_impl(__first1, __last1, __first2, __last2, __result, __comp, __proj1, __proj2);
+ }
+
+ template <
+ input_range _Range1,
+ input_range _Range2,
+ weakly_incrementable _OutIter,
+ class _Comp = less,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires mergeable<
+ iterator_t<_Range1>,
+ iterator_t<_Range2>,
+ _OutIter,
+ _Comp,
+ _Proj1,
+ _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr merge_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>, _OutIter>
+ operator()(
+ _Range1&& __range1,
+ _Range2&& __range2,
+ _OutIter __result,
+ _Comp __comp = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ return __merge::__merge_impl(
+ ranges::begin(__range1),
+ ranges::end(__range1),
+ ranges::begin(__range2),
+ ranges::end(__range2),
+ __result,
+ __comp,
+ __proj1,
+ __proj2);
+ }
+};
+
+} // namespace __merge
+
+inline namespace __cpo {
+ inline constexpr auto merge = __merge::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_MERGE_H
diff --git a/libcxx/include/__algorithm/ranges_nth_element.h b/libcxx/include/__algorithm/ranges_nth_element.h
new file mode 100644
index 000000000000..2a929eacb89d
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_nth_element.h
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H
+#define _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H
+
+#include <__algorithm/make_projected.h>
+#include <__algorithm/nth_element.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__iterator/projected.h>
+#include <__iterator/sortable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __nth_element {
+
+struct __fn {
+ template <class _Iter, class _Sent, class _Comp, class _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ _Iter __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) {
+ auto __last_iter = ranges::next(__first, __last);
+
+ auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ std::__nth_element_impl(std::move(__first), std::move(__nth), __last_iter, __projected_comp);
+
+ return __last_iter;
+ }
+
+ template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<_Iter, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Iter __nth, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ return __nth_element_fn_impl(std::move(__first), std::move(__nth), std::move(__last), __comp, __proj);
+ }
+
+ template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<iterator_t<_Range>, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __nth, _Comp __comp = {},
+ _Proj __proj = {}) const {
+ return __nth_element_fn_impl(ranges::begin(__r), std::move(__nth), ranges::end(__r), __comp, __proj);
+ }
+};
+
+} // namespace __nth_element
+
+inline namespace __cpo {
+ inline constexpr auto nth_element = __nth_element::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H
diff --git a/libcxx/include/__algorithm/ranges_partial_sort_copy.h b/libcxx/include/__algorithm/ranges_partial_sort_copy.h
new file mode 100644
index 000000000000..55ad2ca4e686
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_partial_sort_copy.h
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H
+#define _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H
+
+#include <__algorithm/in_out_result.h>
+#include <__algorithm/make_projected.h>
+#include <__algorithm/partial_sort_copy.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__iterator/sortable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter, class _OutIter>
+using partial_sort_copy_result = in_out_result<_InIter, _OutIter>;
+
+namespace __partial_sort_copy {
+
+struct __fn {
+
+ template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
+ random_access_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
+ class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity>
+ requires indirectly_copyable<_Iter1, _Iter2> && sortable<_Iter2, _Comp, _Proj2> &&
+ indirect_strict_weak_order<_Comp, projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ partial_sort_copy_result<_Iter1, _Iter2>
+ operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result_first, _Sent2 __result_last,
+ _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__result_first; (void)__result_last; (void)__comp; (void)__proj1; (void)__proj2;
+ return {};
+ }
+
+ template <input_range _Range1, random_access_range _Range2, class _Comp = ranges::less,
+ class _Proj1 = identity, class _Proj2 = identity>
+ requires indirectly_copyable<iterator_t<_Range1>, iterator_t<_Range2>> &&
+ sortable<iterator_t<_Range2>, _Comp, _Proj2> &&
+ indirect_strict_weak_order<_Comp, projected<iterator_t<_Range1>, _Proj1>,
+ projected<iterator_t<_Range2>, _Proj2>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ partial_sort_copy_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>>
+ operator()(_Range1&& __range, _Range2&& __result_range, _Comp __comp = {},
+ _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+ // TODO: implement
+ (void)__range; (void)__result_range; (void)__comp; (void)__proj1; (void)__proj2;
+ return {};
+ }
+
+};
+
+} // namespace __partial_sort_copy
+
+inline namespace __cpo {
+ inline constexpr auto partial_sort_copy = __partial_sort_copy::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H
diff --git a/libcxx/include/__algorithm/ranges_partition.h b/libcxx/include/__algorithm/ranges_partition.h
new file mode 100644
index 000000000000..c145e7bdb4a2
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_partition.h
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_PARTITION_H
+#define _LIBCPP___ALGORITHM_RANGES_PARTITION_H
+
+#include <__algorithm/make_projected.h>
+#include <__algorithm/partition.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/permutable.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__ranges/subrange.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __partition {
+
+struct __fn {
+
+ template <permutable _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+ indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__pred; (void)__proj;
+ return {};
+ }
+
+ template <forward_range _Range, class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+ requires permutable<iterator_t<_Range>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__pred; (void)__proj;
+ return {};
+ }
+
+};
+
+} // namespace __partition
+
+inline namespace __cpo {
+ inline constexpr auto partition = __partition::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_H
diff --git a/libcxx/include/__algorithm/ranges_partition_copy.h b/libcxx/include/__algorithm/ranges_partition_copy.h
new file mode 100644
index 000000000000..f55089b94ea5
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_partition_copy.h
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H
+#define _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H
+
+#include <__algorithm/in_out_out_result.h>
+#include <__algorithm/make_projected.h>
+#include <__algorithm/partition_copy.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter, class _OutIter1, class _OutIter2>
+using partition_copy_result = in_out_out_result<_InIter, _OutIter1, _OutIter2>;
+
+namespace __partition_copy {
+
+struct __fn {
+
+ template <input_iterator _InIter, sentinel_for<_InIter> _Sent,
+ weakly_incrementable _OutIter1, weakly_incrementable _OutIter2,
+ class _Proj = identity, indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
+ requires indirectly_copyable<_InIter, _OutIter1> && indirectly_copyable<_InIter, _OutIter2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ partition_copy_result<_InIter, _OutIter1, _OutIter2>
+ operator()(_InIter __first, _Sent __last, _OutIter1 __out_true, _OutIter2 __out_false,
+ _Pred __pred, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__out_true; (void)__out_false; (void)__pred; (void)__proj;
+ return {};
+ }
+
+ template <input_range _Range, weakly_incrementable _OutIter1, weakly_incrementable _OutIter2,
+ class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+ requires indirectly_copyable<iterator_t<_Range>, _OutIter1> && indirectly_copyable<iterator_t<_Range>, _OutIter2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ partition_copy_result<borrowed_iterator_t<_Range>, _OutIter1, _OutIter2>
+ operator()(_Range&& __range, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__out_true; (void)__out_false; (void)__pred; (void)__proj;
+ return {};
+ }
+
+};
+
+} // namespace __partition_copy
+
+inline namespace __cpo {
+ inline constexpr auto partition_copy = __partition_copy::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H
diff --git a/libcxx/include/__algorithm/ranges_partition_point.h b/libcxx/include/__algorithm/ranges_partition_point.h
new file mode 100644
index 000000000000..336b29f63284
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_partition_point.h
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H
+#define _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H
+
+#include <__algorithm/make_projected.h>
+#include <__algorithm/partition_point.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __partition_point {
+
+struct __fn {
+
+ template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+ indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__pred; (void)__proj;
+ return {};
+ }
+
+ template <forward_range _Range, class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__pred; (void)__proj;
+ return {};
+ }
+
+};
+
+} // namespace __partition_point
+
+inline namespace __cpo {
+ inline constexpr auto partition_point = __partition_point::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H
diff --git a/libcxx/include/__algorithm/ranges_pop_heap.h b/libcxx/include/__algorithm/ranges_pop_heap.h
new file mode 100644
index 000000000000..d0b8314e5b0a
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_pop_heap.h
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H
+#define _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H
+
+#include <__algorithm/make_projected.h>
+#include <__algorithm/pop_heap.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__iterator/projected.h>
+#include <__iterator/sortable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __pop_heap {
+
+struct __fn {
+ template <class _Iter, class _Sent, class _Comp, class _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ _Iter __pop_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+ auto __last_iter = ranges::next(__first, __last);
+ auto __len = __last_iter - __first;
+
+ auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ std::__pop_heap(std::move(__first), __last_iter, __projected_comp, __len);
+
+ return __last_iter;
+ }
+
+ template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<_Iter, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ return __pop_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
+ }
+
+ template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<iterator_t<_Range>, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+ return __pop_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
+ }
+};
+
+} // namespace __pop_heap
+
+inline namespace __cpo {
+ inline constexpr auto pop_heap = __pop_heap::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H
diff --git a/libcxx/include/__algorithm/ranges_push_heap.h b/libcxx/include/__algorithm/ranges_push_heap.h
new file mode 100644
index 000000000000..e46ad19cfed7
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_push_heap.h
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H
+#define _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H
+
+#include <__algorithm/make_projected.h>
+#include <__algorithm/push_heap.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__iterator/projected.h>
+#include <__iterator/sortable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __push_heap {
+
+struct __fn {
+ template <class _Iter, class _Sent, class _Comp, class _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ _Iter __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+ auto __last_iter = ranges::next(__first, __last);
+
+ auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ std::__push_heap(std::move(__first), __last_iter, __projected_comp);
+
+ return __last_iter;
+ }
+
+ template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<_Iter, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ return __push_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
+ }
+
+ template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<iterator_t<_Range>, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+ return __push_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
+ }
+};
+
+} // namespace __push_heap
+
+inline namespace __cpo {
+ inline constexpr auto push_heap = __push_heap::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H
diff --git a/libcxx/include/__algorithm/ranges_remove.h b/libcxx/include/__algorithm/ranges_remove.h
new file mode 100644
index 000000000000..a6a1200763d2
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_remove.h
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_H
+#define _LIBCPP___ALGORITHM_RANGES_REMOVE_H
+#include <__config>
+
+#include <__algorithm/ranges_remove_if.h>
+#include <__functional/identity.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/permutable.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/subrange.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __remove {
+struct __fn {
+
+ template <permutable _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity>
+ requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
+ auto __pred = [&](auto&& __other) { return __value == __other; };
+ return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj);
+ }
+
+ template <forward_range _Range, class _Type, class _Proj = identity>
+ requires permutable<iterator_t<_Range>>
+ && indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const {
+ auto __pred = [&](auto&& __other) { return __value == __other; };
+ return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
+ }
+};
+} // namespace __remove
+
+inline namespace __cpo {
+ inline constexpr auto remove = __remove::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_H
diff --git a/libcxx/include/__algorithm/ranges_remove_copy.h b/libcxx/include/__algorithm/ranges_remove_copy.h
new file mode 100644
index 000000000000..16e9009e7ef0
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_remove_copy.h
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H
+#define _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H
+
+#include <__algorithm/in_out_result.h>
+#include <__algorithm/make_projected.h>
+#include <__algorithm/remove_copy.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter, class _OutIter>
+using remove_copy_result = in_out_result<_InIter, _OutIter>;
+
+namespace __remove_copy {
+
+struct __fn {
+
+ template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter, class _Type,
+ class _Proj = identity>
+ requires indirectly_copyable<_InIter, _OutIter> &&
+ indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _Type*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ remove_copy_result<_InIter, _OutIter>
+ operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__result; (void)__value; (void)__proj;
+ return {};
+ }
+
+ template <input_range _Range, weakly_incrementable _OutIter, class _Type, class _Proj = identity>
+ requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
+ indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ remove_copy_result<borrowed_iterator_t<_Range>, _OutIter>
+ operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__result; (void)__value; (void)__proj;
+ return {};
+ }
+
+};
+
+} // namespace __remove_copy
+
+inline namespace __cpo {
+ inline constexpr auto remove_copy = __remove_copy::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H
diff --git a/libcxx/include/__algorithm/ranges_remove_copy_if.h b/libcxx/include/__algorithm/ranges_remove_copy_if.h
new file mode 100644
index 000000000000..4eafe425b8e3
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_remove_copy_if.h
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H
+#define _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H
+
+#include <__algorithm/in_out_result.h>
+#include <__algorithm/make_projected.h>
+#include <__algorithm/remove_copy_if.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter, class _OutIter>
+using remove_copy_if_result = in_out_result<_InIter, _OutIter>;
+
+namespace __remove_copy_if {
+
+struct __fn {
+
+ template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter,
+ class _Proj = identity, indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
+ requires indirectly_copyable<_InIter, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ remove_copy_if_result<_InIter, _OutIter>
+ operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__result; (void)__pred; (void)__proj;
+ return {};
+ }
+
+ template <input_range _Range, weakly_incrementable _OutIter, class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+ requires indirectly_copyable<iterator_t<_Range>, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ remove_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
+ operator()(_Range&& __range, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__result; (void)__pred; (void)__proj;
+ return {};
+ }
+
+};
+
+} // namespace __remove_copy_if
+
+inline namespace __cpo {
+ inline constexpr auto remove_copy_if = __remove_copy_if::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H
diff --git a/libcxx/include/__algorithm/ranges_remove_if.h b/libcxx/include/__algorithm/ranges_remove_if.h
new file mode 100644
index 000000000000..d4e382e551c6
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_remove_if.h
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H
+#define _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H
+#include <__config>
+
+#include <__algorithm/ranges_find_if.h>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/permutable.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/subrange.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _Iter, class _Sent, class _Proj, class _Pred>
+_LIBCPP_HIDE_FROM_ABI constexpr
+subrange<_Iter> __remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+ auto __new_end = ranges::__find_if_impl(__first, __last, __pred, __proj);
+ if (__new_end == __last)
+ return {__new_end, __new_end};
+
+ _Iter __i = __new_end;
+ while (++__i != __last) {
+ if (!std::invoke(__pred, std::invoke(__proj, *__i))) {
+ *__new_end = ranges::iter_move(__i);
+ ++__new_end;
+ }
+ }
+ return {__new_end, __i};
+}
+
+namespace __remove_if {
+struct __fn {
+
+ template <permutable _Iter, sentinel_for<_Iter> _Sent,
+ class _Proj = identity,
+ indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
+ return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj);
+ }
+
+ template <forward_range _Range,
+ class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+ requires permutable<iterator_t<_Range>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+ return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
+ }
+
+};
+} // namespace __remove_if
+
+inline namespace __cpo {
+ inline constexpr auto remove_if = __remove_if::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H
diff --git a/libcxx/include/__algorithm/ranges_replace_copy.h b/libcxx/include/__algorithm/ranges_replace_copy.h
new file mode 100644
index 000000000000..19ef635d6f15
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_replace_copy.h
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H
+#define _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H
+
+#include <__algorithm/in_out_result.h>
+#include <__algorithm/make_projected.h>
+#include <__algorithm/replace_copy.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter, class _OutIter>
+using replace_copy_result = in_out_result<_InIter, _OutIter>;
+
+namespace __replace_copy {
+
+struct __fn {
+
+ template <input_iterator _InIter, sentinel_for<_InIter> _Sent, class _Type1, class _Type2,
+ output_iterator<const _Type2&> _OutIter, class _Proj = identity>
+ requires indirectly_copyable<_InIter, _OutIter> &&
+ indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _Type1*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ replace_copy_result<_InIter, _OutIter>
+ operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type1& __old_value, const _Type2& __new_value,
+ _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__result; (void)__old_value; (void)__new_value; (void)__proj;
+ return {};
+ }
+
+ template <input_range _Range, class _Type1, class _Type2, output_iterator<const _Type2&> _OutIter,
+ class _Proj = identity>
+ requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
+ indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type1*>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ replace_copy_result<borrowed_iterator_t<_Range>, _OutIter>
+ operator()(_Range&& __range, _OutIter __result, const _Type1& __old_value, const _Type2& __new_value,
+ _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__result; (void)__old_value; (void)__new_value; (void)__proj;
+ return {};
+ }
+
+};
+
+} // namespace __replace_copy
+
+inline namespace __cpo {
+ inline constexpr auto replace_copy = __replace_copy::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H
diff --git a/libcxx/include/__algorithm/ranges_replace_copy_if.h b/libcxx/include/__algorithm/ranges_replace_copy_if.h
new file mode 100644
index 000000000000..2a908e2057af
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_replace_copy_if.h
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H
+#define _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H
+
+#include <__algorithm/in_out_result.h>
+#include <__algorithm/make_projected.h>
+#include <__algorithm/replace_copy_if.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter, class _OutIter>
+using replace_copy_if_result = in_out_result<_InIter, _OutIter>;
+
+namespace __replace_copy_if {
+
+struct __fn {
+
+ template <input_iterator _InIter, sentinel_for<_InIter> _Sent, class _Type, output_iterator<const _Type&> _OutIter,
+ class _Proj = identity, indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
+ requires indirectly_copyable<_InIter, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ replace_copy_if_result<_InIter, _OutIter>
+ operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, const _Type& __new_value,
+ _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__result; (void)__pred; (void)__new_value; (void)__proj;
+ return {};
+ }
+
+ template <input_range _Range, class _Type, output_iterator<const _Type&> _OutIter, class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+ requires indirectly_copyable<iterator_t<_Range>, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ replace_copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
+ operator()(_Range&& __range, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__result; (void)__pred; (void)__new_value; (void)__proj;
+ return {};
+ }
+
+};
+
+} // namespace __replace_copy_if
+
+inline namespace __cpo {
+ inline constexpr auto replace_copy_if = __replace_copy_if::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H
diff --git a/libcxx/include/__algorithm/ranges_reverse_copy.h b/libcxx/include/__algorithm/ranges_reverse_copy.h
new file mode 100644
index 000000000000..e2da9b484aaf
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_reverse_copy.h
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H
+#define _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H
+
+#include <__algorithm/in_out_result.h>
+#include <__algorithm/ranges_copy.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/next.h>
+#include <__iterator/reverse_iterator.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__ranges/subrange.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter, class _OutIter>
+using reverse_copy_result = in_out_result<_InIter, _OutIter>;
+
+namespace __reverse_copy {
+struct __fn {
+
+ template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
+ requires indirectly_copyable<_InIter, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ reverse_copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
+ return (*this)(subrange(std::move(__first), std::move(__last)), std::move(__result));
+ }
+
+ template <bidirectional_range _Range, weakly_incrementable _OutIter>
+ requires indirectly_copyable<iterator_t<_Range>, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ reverse_copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __range, _OutIter __result) const {
+ auto __ret = ranges::copy(std::__reverse_range(__range), std::move(__result));
+ return {ranges::next(ranges::begin(__range), ranges::end(__range)), std::move(__ret.out)};
+ }
+
+};
+} // namespace __reverse_copy
+
+inline namespace __cpo {
+ inline constexpr auto reverse_copy = __reverse_copy::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H
diff --git a/libcxx/include/__algorithm/ranges_rotate_copy.h b/libcxx/include/__algorithm/ranges_rotate_copy.h
new file mode 100644
index 000000000000..d7a282c86750
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_rotate_copy.h
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H
+#define _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H
+
+#include <__algorithm/in_out_result.h>
+#include <__algorithm/ranges_copy.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/reverse_iterator.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter, class _OutIter>
+using rotate_copy_result = in_out_result<_InIter, _OutIter>;
+
+namespace __rotate_copy {
+struct __fn {
+
+ template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
+ requires indirectly_copyable<_InIter, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ rotate_copy_result<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __middle, _Sent __last, _OutIter __result) const {
+ auto __res1 = ranges::copy(__middle, __last, std::move(__result));
+ auto __res2 = ranges::copy(__first, __middle, std::move(__res1.out));
+ return {std::move(__res1.in), std::move(__res2.out)};
+ }
+
+ template <bidirectional_range _Range, weakly_incrementable _OutIter>
+ requires indirectly_copyable<iterator_t<_Range>, _OutIter>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ rotate_copy_result<borrowed_iterator_t<_Range>, _OutIter>
+ operator()(_Range&& __range, iterator_t<_Range> __middle, _OutIter __result) const {
+ return (*this)(ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__result));
+ }
+
+};
+} // namespace __rotate_copy
+
+inline namespace __cpo {
+ inline constexpr auto rotate_copy = __rotate_copy::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H
diff --git a/libcxx/include/__algorithm/ranges_search.h b/libcxx/include/__algorithm/ranges_search.h
new file mode 100644
index 000000000000..0564bbe1f8b3
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_search.h
@@ -0,0 +1,134 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_SEARCH_H
+#define _LIBCPP___ALGORITHM_RANGES_SEARCH_H
+
+#include <__algorithm/iterator_operations.h>
+#include <__algorithm/search.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/advance.h>
+#include <__iterator/concepts.h>
+#include <__iterator/distance.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/size.h>
+#include <__ranges/subrange.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __search {
+struct __fn {
+ template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
+ _LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Iter1> __ranges_search_impl(
+ _Iter1 __first1,
+ _Sent1 __last1,
+ _Iter2 __first2,
+ _Sent2 __last2,
+ _Pred& __pred,
+ _Proj1& __proj1,
+ _Proj2& __proj2) {
+ if constexpr (sized_sentinel_for<_Sent2, _Iter2>) {
+ auto __size2 = ranges::distance(__first2, __last2);
+ if (__size2 == 0)
+ return {__first1, __first1};
+
+ if constexpr (sized_sentinel_for<_Sent1, _Iter1>) {
+ auto __size1 = ranges::distance(__first1, __last1);
+ if (__size1 < __size2) {
+ ranges::advance(__first1, __last1);
+ return {__first1, __first1};
+ }
+
+ if constexpr (random_access_iterator<_Iter1> && random_access_iterator<_Iter2>) {
+ auto __ret = std::__search_random_access_impl<_RangeAlgPolicy>(
+ __first1, __last1, __first2, __last2, __pred, __proj1, __proj2, __size1, __size2);
+ return {__ret.first, __ret.second};
+ }
+ }
+ }
+
+ auto __ret =
+ std::__search_forward_impl<_RangeAlgPolicy>(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2);
+ return {__ret.first, __ret.second};
+ }
+
+ template <forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
+ forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
+ class _Pred = ranges::equal_to,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Pred __pred = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ return __ranges_search_impl(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2);
+ }
+
+ template <forward_range _Range1,
+ forward_range _Range2,
+ class _Pred = ranges::equal_to,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_subrange_t<_Range1> operator()(_Range1&& __range1,
+ _Range2&& __range2,
+ _Pred __pred = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ auto __first1 = ranges::begin(__range1);
+ if constexpr (sized_range<_Range2>) {
+ auto __size2 = ranges::size(__range2);
+ if (__size2 == 0)
+ return {__first1, __first1};
+ if constexpr (sized_range<_Range1>) {
+ auto __size1 = ranges::size(__range1);
+ if (__size1 < __size2) {
+ ranges::advance(__first1, ranges::end(__range1));
+ return {__first1, __first1};
+ }
+ }
+ }
+
+ return __ranges_search_impl(
+ ranges::begin(__range1),
+ ranges::end(__range1),
+ ranges::begin(__range2),
+ ranges::end(__range2),
+ __pred,
+ __proj1,
+ __proj2);
+ }
+
+};
+} // namespace __search
+
+inline namespace __cpo {
+ inline constexpr auto search = __search::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_H
diff --git a/libcxx/include/__algorithm/ranges_search_n.h b/libcxx/include/__algorithm/ranges_search_n.h
new file mode 100644
index 000000000000..29fdbfb1c725
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_search_n.h
@@ -0,0 +1,120 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H
+#define _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H
+
+#include <__algorithm/iterator_operations.h>
+#include <__algorithm/search_n.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/advance.h>
+#include <__iterator/concepts.h>
+#include <__iterator/distance.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__iterator/iterator_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/size.h>
+#include <__ranges/subrange.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __search_n {
+struct __fn {
+
+ template <class _Iter1, class _Sent1, class _SizeT, class _Type, class _Pred, class _Proj>
+ _LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Iter1> __ranges_search_n_impl(
+ _Iter1 __first, _Sent1 __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) {
+ if (__count == 0)
+ return {__first, __first};
+
+ if constexpr (sized_sentinel_for<_Sent1, _Iter1>) {
+ auto __size = ranges::distance(__first, __last);
+ if (__size < __count) {
+ ranges::advance(__first, __last);
+ return {__first, __first};
+ }
+
+ if constexpr (random_access_iterator<_Iter1>) {
+ auto __ret = __search_n_random_access_impl<_RangeAlgPolicy>(__first, __last,
+ __count,
+ __value,
+ __pred,
+ __proj,
+ __size);
+ return {std::move(__ret.first), std::move(__ret.second)};
+ }
+ }
+
+ auto __ret = std::__search_n_forward_impl<_RangeAlgPolicy>(__first, __last,
+ __count,
+ __value,
+ __pred,
+ __proj);
+ return {std::move(__ret.first), std::move(__ret.second)};
+ }
+
+ template <forward_iterator _Iter, sentinel_for<_Iter> _Sent,
+ class _Type,
+ class _Pred = ranges::equal_to,
+ class _Proj = identity>
+ requires indirectly_comparable<_Iter, const _Type*, _Pred, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ subrange<_Iter> operator()(_Iter __first, _Sent __last,
+ iter_difference_t<_Iter> __count,
+ const _Type& __value,
+ _Pred __pred = {},
+ _Proj __proj = _Proj{}) const {
+ return __ranges_search_n_impl(__first, __last, __count, __value, __pred, __proj);
+ }
+
+ template <forward_range _Range, class _Type, class _Pred = ranges::equal_to, class _Proj = identity>
+ requires indirectly_comparable<iterator_t<_Range>, const _Type*, _Pred, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_subrange_t<_Range> operator()(_Range&& __range,
+ range_difference_t<_Range> __count,
+ const _Type& __value,
+ _Pred __pred = {},
+ _Proj __proj = {}) const {
+ auto __first = ranges::begin(__range);
+ if (__count <= 0)
+ return {__first, __first};
+ if constexpr (sized_range<_Range>) {
+ auto __size1 = ranges::size(__range);
+ if (__size1 < static_cast<range_size_t<_Range>>(__count)) {
+ ranges::advance(__first, ranges::end(__range));
+ return {__first, __first};
+ }
+ }
+
+ return __ranges_search_n_impl(ranges::begin(__range), ranges::end(__range), __count, __value, __pred, __proj);
+ }
+};
+} // namespace __search_n
+
+inline namespace __cpo {
+ inline constexpr auto search_n = __search_n::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H
diff --git a/libcxx/include/__algorithm/ranges_set_difference.h b/libcxx/include/__algorithm/ranges_set_difference.h
new file mode 100644
index 000000000000..4eb3efad3895
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_set_difference.h
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H
+#define _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H
+
+#include <__algorithm/in_out_result.h>
+#include <__algorithm/make_projected.h>
+#include <__algorithm/set_difference.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/mergeable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__type_traits/decay.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter, class _OutIter>
+using set_difference_result = in_out_result<_InIter, _OutIter>;
+
+namespace __set_difference {
+
+struct __fn {
+ template <
+ input_iterator _InIter1,
+ sentinel_for<_InIter1> _Sent1,
+ input_iterator _InIter2,
+ sentinel_for<_InIter2> _Sent2,
+ weakly_incrementable _OutIter,
+ class _Comp = less,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result<_InIter1, _OutIter> operator()(
+ _InIter1 __first1,
+ _Sent1 __last1,
+ _InIter2 __first2,
+ _Sent2 __last2,
+ _OutIter __result,
+ _Comp __comp = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ auto __ret = std::__set_difference(
+ __first1, __last1, __first2, __last2, __result, ranges::__make_projected_comp(__comp, __proj1, __proj2));
+ return {std::move(__ret.first), std::move(__ret.second)};
+ }
+
+ template <
+ input_range _Range1,
+ input_range _Range2,
+ weakly_incrementable _OutIter,
+ class _Comp = less,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result<borrowed_iterator_t<_Range1>, _OutIter>
+ operator()(
+ _Range1&& __range1,
+ _Range2&& __range2,
+ _OutIter __result,
+ _Comp __comp = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ auto __ret = std::__set_difference(
+ ranges::begin(__range1),
+ ranges::end(__range1),
+ ranges::begin(__range2),
+ ranges::end(__range2),
+ __result,
+ ranges::__make_projected_comp(__comp, __proj1, __proj2));
+ return {std::move(__ret.first), std::move(__ret.second)};
+ }
+};
+
+} // namespace __set_difference
+
+inline namespace __cpo {
+ inline constexpr auto set_difference = __set_difference::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H
diff --git a/libcxx/include/__algorithm/ranges_set_intersection.h b/libcxx/include/__algorithm/ranges_set_intersection.h
new file mode 100644
index 000000000000..05af91ae29e5
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_set_intersection.h
@@ -0,0 +1,117 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H
+#define _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H
+
+#include <__algorithm/in_in_out_result.h>
+#include <__algorithm/iterator_operations.h>
+#include <__algorithm/make_projected.h>
+#include <__algorithm/set_intersection.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/mergeable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter1, class _InIter2, class _OutIter>
+using set_intersection_result = in_in_out_result<_InIter1, _InIter2, _OutIter>;
+
+namespace __set_intersection {
+
+struct __fn {
+ template <
+ input_iterator _InIter1,
+ sentinel_for<_InIter1> _Sent1,
+ input_iterator _InIter2,
+ sentinel_for<_InIter2> _Sent2,
+ weakly_incrementable _OutIter,
+ class _Comp = less,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<_InIter1, _InIter2, _OutIter> operator()(
+ _InIter1 __first1,
+ _Sent1 __last1,
+ _InIter2 __first2,
+ _Sent2 __last2,
+ _OutIter __result,
+ _Comp __comp = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ auto __ret = std::__set_intersection<_RangeAlgPolicy>(
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::move(__result),
+ ranges::__make_projected_comp(__comp, __proj1, __proj2));
+ return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)};
+ }
+
+ template <
+ input_range _Range1,
+ input_range _Range2,
+ weakly_incrementable _OutIter,
+ class _Comp = less,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires mergeable<
+ iterator_t<_Range1>,
+ iterator_t<_Range2>,
+ _OutIter,
+ _Comp,
+ _Proj1,
+ _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<borrowed_iterator_t<_Range1>,
+ borrowed_iterator_t<_Range2>,
+ _OutIter>
+ operator()(
+ _Range1&& __range1,
+ _Range2&& __range2,
+ _OutIter __result,
+ _Comp __comp = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ auto __ret = std::__set_intersection<_RangeAlgPolicy>(
+ ranges::begin(__range1),
+ ranges::end(__range1),
+ ranges::begin(__range2),
+ ranges::end(__range2),
+ std::move(__result),
+ ranges::__make_projected_comp(__comp, __proj1, __proj2));
+ return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)};
+ }
+};
+
+} // namespace __set_intersection
+
+inline namespace __cpo {
+ inline constexpr auto set_intersection = __set_intersection::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H
diff --git a/libcxx/include/__algorithm/ranges_set_symmetric_difference.h b/libcxx/include/__algorithm/ranges_set_symmetric_difference.h
new file mode 100644
index 000000000000..c54cf3a65112
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_set_symmetric_difference.h
@@ -0,0 +1,116 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H
+#define _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H
+
+#include <__algorithm/in_in_out_result.h>
+#include <__algorithm/make_projected.h>
+#include <__algorithm/set_symmetric_difference.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/mergeable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter1, class _InIter2, class _OutIter>
+using set_symmetric_difference_result = in_in_out_result<_InIter1, _InIter2, _OutIter>;
+
+namespace __set_symmetric_difference {
+
+struct __fn {
+ template <
+ input_iterator _InIter1,
+ sentinel_for<_InIter1> _Sent1,
+ input_iterator _InIter2,
+ sentinel_for<_InIter2> _Sent2,
+ weakly_incrementable _OutIter,
+ class _Comp = ranges::less,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result<_InIter1, _InIter2, _OutIter> operator()(
+ _InIter1 __first1,
+ _Sent1 __last1,
+ _InIter2 __first2,
+ _Sent2 __last2,
+ _OutIter __result,
+ _Comp __comp = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ auto __ret = std::__set_symmetric_difference(
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::move(__result),
+ ranges::__make_projected_comp(__comp, __proj1, __proj2));
+ return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)};
+ }
+
+ template <
+ input_range _Range1,
+ input_range _Range2,
+ weakly_incrementable _OutIter,
+ class _Comp = ranges::less,
+ class _Proj1 = identity,
+ class _Proj2 = identity>
+ requires mergeable<
+ iterator_t<_Range1>,
+ iterator_t<_Range2>,
+ _OutIter,
+ _Comp,
+ _Proj1,
+ _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result<borrowed_iterator_t<_Range1>,
+ borrowed_iterator_t<_Range2>,
+ _OutIter>
+ operator()(
+ _Range1&& __range1,
+ _Range2&& __range2,
+ _OutIter __result,
+ _Comp __comp = {},
+ _Proj1 __proj1 = {},
+ _Proj2 __proj2 = {}) const {
+ auto __ret = std::__set_symmetric_difference(
+ ranges::begin(__range1),
+ ranges::end(__range1),
+ ranges::begin(__range2),
+ ranges::end(__range2),
+ std::move(__result),
+ ranges::__make_projected_comp(__comp, __proj1, __proj2));
+ return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)};
+ }
+};
+
+} // namespace __set_symmetric_difference
+
+inline namespace __cpo {
+ inline constexpr auto set_symmetric_difference = __set_symmetric_difference::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H
diff --git a/libcxx/include/__algorithm/ranges_set_union.h b/libcxx/include/__algorithm/ranges_set_union.h
new file mode 100644
index 000000000000..39537503b98f
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_set_union.h
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_SET_UNION_H
+#define _LIBCPP___ALGORITHM_RANGES_SET_UNION_H
+
+#include <__algorithm/in_in_out_result.h>
+#include <__algorithm/make_projected.h>
+#include <__algorithm/set_union.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/mergeable.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter1, class _InIter2, class _OutIter>
+using set_union_result = in_in_out_result<_InIter1, _InIter2, _OutIter>;
+
+namespace __set_union {
+
+struct __fn {
+
+ template <input_iterator _InIter1, sentinel_for<_InIter1> _Sent1,
+ input_iterator _InIter2, sentinel_for<_InIter2> _Sent2,
+ weakly_incrementable _OutIter, class _Comp = ranges::less,
+ class _Proj1 = identity, class _Proj2 = identity>
+ requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ set_union_result<_InIter1, _InIter2, _OutIter>
+ operator()(_InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Comp __comp = {},
+ _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+ // TODO: implement
+ (void)__first1; (void)__last1; (void)__first2; (void)__last2; (void)__result; (void)__comp; (void)__proj1;
+ (void)__proj2;
+ return {};
+ }
+
+ template <input_range _Range1, input_range _Range2, weakly_incrementable _OutIter,
+ class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity>
+ requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ set_union_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>, _OutIter>
+ operator()(_Range1&& __range1, _Range2&& __range2, _OutIter __result, _Comp __comp = {},
+ _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
+ // TODO: implement
+ (void)__range1; (void)__range2; (void)__result; (void)__comp; (void)__proj1; (void)__proj2;
+ return {};
+ }
+
+};
+
+} // namespace __set_union
+
+inline namespace __cpo {
+ inline constexpr auto set_union = __set_union::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_SET_UNION_H
diff --git a/libcxx/include/__algorithm/ranges_shuffle.h b/libcxx/include/__algorithm/ranges_shuffle.h
new file mode 100644
index 000000000000..bf9c28b4ce26
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_shuffle.h
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H
+#define _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H
+
+#include <__algorithm/make_projected.h>
+#include <__algorithm/shuffle.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/permutable.h>
+#include <__iterator/projected.h>
+#include <__random/uniform_random_bit_generator.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__type_traits/remove_reference.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __shuffle {
+
+struct __fn {
+
+ template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Gen>
+ requires permutable<_Iter> && uniform_random_bit_generator<remove_reference_t<_Gen>>
+ _LIBCPP_HIDE_FROM_ABI
+ _Iter operator()(_Iter __first, _Sent __last, _Gen&& __gen) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__gen;
+ return {};
+ }
+
+ template<random_access_range _Range, class _Gen>
+ requires permutable<iterator_t<_Range>> && uniform_random_bit_generator<remove_reference_t<_Gen>>
+ _LIBCPP_HIDE_FROM_ABI
+ borrowed_iterator_t<_Range> operator()(_Range&& __range, _Gen&& __gen) const {
+ // TODO: implement
+ (void)__range; (void)__gen;
+ return {};
+ }
+
+};
+
+} // namespace __shuffle
+
+inline namespace __cpo {
+ inline constexpr auto shuffle = __shuffle::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H
diff --git a/libcxx/include/__algorithm/ranges_sort_heap.h b/libcxx/include/__algorithm/ranges_sort_heap.h
new file mode 100644
index 000000000000..c753e20c44a6
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_sort_heap.h
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H
+#define _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H
+
+#include <__algorithm/make_projected.h>
+#include <__algorithm/sort_heap.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__iterator/projected.h>
+#include <__iterator/sortable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __sort_heap {
+
+struct __fn {
+ template <class _Iter, class _Sent, class _Comp, class _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr static
+ _Iter __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+ auto __last_iter = ranges::next(__first, __last);
+
+ auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ std::__sort_heap(std::move(__first), __last_iter, __projected_comp);
+
+ return __last_iter;
+ }
+
+ template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<_Iter, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ return __sort_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
+ }
+
+ template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity>
+ requires sortable<iterator_t<_Range>, _Comp, _Proj>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
+ return __sort_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
+ }
+};
+
+} // namespace __sort_heap
+
+inline namespace __cpo {
+ inline constexpr auto sort_heap = __sort_heap::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H
diff --git a/libcxx/include/__algorithm/ranges_stable_partition.h b/libcxx/include/__algorithm/ranges_stable_partition.h
new file mode 100644
index 000000000000..178c953ebdae
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_stable_partition.h
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H
+#define _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H
+
+#include <__algorithm/make_projected.h>
+#include <__algorithm/stable_partition.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/permutable.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__ranges/subrange.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __stable_partition {
+
+struct __fn {
+
+ template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+ indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
+ requires permutable<_Iter>
+ _LIBCPP_HIDE_FROM_ABI
+ subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__pred; (void)__proj;
+ return {};
+ }
+
+ template <bidirectional_range _Range, class _Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
+ requires permutable<iterator_t<_Range>>
+ _LIBCPP_HIDE_FROM_ABI
+ borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__pred; (void)__proj;
+ return {};
+ }
+
+};
+
+} // namespace __stable_partition
+
+inline namespace __cpo {
+ inline constexpr auto stable_partition = __stable_partition::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H
diff --git a/libcxx/include/__algorithm/ranges_unique.h b/libcxx/include/__algorithm/ranges_unique.h
new file mode 100644
index 000000000000..bdf755e9406e
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_unique.h
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_UNIQUE_H
+#define _LIBCPP___ALGORITHM_RANGES_UNIQUE_H
+
+#include <__algorithm/make_projected.h>
+#include <__algorithm/unique.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/permutable.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__ranges/subrange.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __unique {
+
+struct __fn {
+
+ template <permutable _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
+ indirect_equivalence_relation<projected<_Iter, _Proj>> _Comp = ranges::equal_to>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ subrange<_Iter> operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__comp; (void)__proj;
+ return {};
+ }
+
+ template <forward_range _Range, class _Proj = identity,
+ indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
+ requires permutable<iterator_t<_Range>>
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ borrowed_subrange_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__comp; (void)__proj;
+ return {};
+ }
+
+};
+
+} // namespace __unique
+
+inline namespace __cpo {
+ inline constexpr auto unique = __unique::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_H
diff --git a/libcxx/include/__algorithm/ranges_unique_copy.h b/libcxx/include/__algorithm/ranges_unique_copy.h
new file mode 100644
index 000000000000..56361aa8ae2f
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_unique_copy.h
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H
+#define _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H
+
+#include <__algorithm/in_out_result.h>
+#include <__algorithm/make_projected.h>
+#include <__algorithm/unique_copy.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/readable_traits.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _InIter, class _OutIter>
+using unique_copy_result = in_out_result<_InIter, _OutIter>;
+
+namespace __unique_copy {
+
+struct __fn {
+
+ template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter, class _Proj = identity,
+ indirect_equivalence_relation<projected<_InIter, _Proj>> _Comp = ranges::equal_to>
+ requires indirectly_copyable<_InIter, _OutIter> &&
+ (forward_iterator<_InIter> ||
+ (input_iterator<_OutIter> && same_as<iter_value_t<_InIter>, iter_value_t<_OutIter>>) ||
+ indirectly_copyable_storable<_InIter, _OutIter>)
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ unique_copy_result<_InIter, _OutIter>
+ operator()(_InIter __first, _Sent __last, _OutIter __result, _Comp __comp = {}, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__first; (void)__last; (void)__result; (void)__comp; (void)__proj;
+ return {};
+ }
+
+ template <input_range _Range, weakly_incrementable _OutIter, class _Proj = identity,
+ indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
+ requires indirectly_copyable<iterator_t<_Range>, _OutIter> &&
+ (forward_iterator<iterator_t<_Range>> ||
+ (input_iterator<_OutIter> && same_as<range_value_t<_Range>, iter_value_t<_OutIter>>) ||
+ indirectly_copyable_storable<iterator_t<_Range>, _OutIter>)
+ _LIBCPP_HIDE_FROM_ABI constexpr
+ unique_copy_result<borrowed_iterator_t<_Range>, _OutIter>
+ operator()(_Range&& __range, _OutIter __result, _Comp __comp = {}, _Proj __proj = {}) const {
+ // TODO: implement
+ (void)__range; (void)__result; (void)__comp; (void)__proj;
+ return {};
+ }
+
+};
+
+} // namespace __unique_copy
+
+inline namespace __cpo {
+ inline constexpr auto unique_copy = __unique_copy::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+#endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H
diff --git a/libcxx/include/__algorithm/ranges_upper_bound.h b/libcxx/include/__algorithm/ranges_upper_bound.h
index 94b5269c86af..3c63249248fa 100644
--- a/libcxx/include/__algorithm/ranges_upper_bound.h
+++ b/libcxx/include/__algorithm/ranges_upper_bound.h
@@ -40,7 +40,7 @@ struct __fn {
return !std::invoke(__comp, __rhs, __lhs);
};
- return std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj);
+ return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj);
}
template <forward_range _Range, class _Type, class _Proj = identity,
@@ -54,7 +54,7 @@ struct __fn {
return !std::invoke(__comp, __rhs, __lhs);
};
- return std::__lower_bound_impl<_RangesIterOps>(ranges::begin(__r),
+ return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r),
ranges::end(__r),
__value,
__comp_lhs_rhs_swapped,
diff --git a/libcxx/include/__algorithm/remove.h b/libcxx/include/__algorithm/remove.h
index c00f96f78a63..8a7e99ba09a1 100644
--- a/libcxx/include/__algorithm/remove.h
+++ b/libcxx/include/__algorithm/remove.h
@@ -22,15 +22,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
-remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
{
- __first = _VSTD::find(__first, __last, __value_);
+ __first = _VSTD::find(__first, __last, __value);
if (__first != __last)
{
_ForwardIterator __i = __first;
while (++__i != __last)
{
- if (!(*__i == __value_))
+ if (!(*__i == __value))
{
*__first = _VSTD::move(*__i);
++__first;
diff --git a/libcxx/include/__algorithm/remove_copy.h b/libcxx/include/__algorithm/remove_copy.h
index a29a385af9ac..55fc1d90a1e7 100644
--- a/libcxx/include/__algorithm/remove_copy.h
+++ b/libcxx/include/__algorithm/remove_copy.h
@@ -20,11 +20,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _OutputIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_OutputIterator
-remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_)
+remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value)
{
for (; __first != __last; ++__first)
{
- if (!(*__first == __value_))
+ if (!(*__first == __value))
{
*__result = *__first;
++__result;
diff --git a/libcxx/include/__algorithm/search.h b/libcxx/include/__algorithm/search.h
index d89ec2b1c5bc..4ead6cac82b7 100644
--- a/libcxx/include/__algorithm/search.h
+++ b/libcxx/include/__algorithm/search.h
@@ -11,9 +11,15 @@
#define _LIBCPP___ALGORITHM_SEARCH_H
#include <__algorithm/comp.h>
+#include <__algorithm/iterator_operations.h>
#include <__config>
+#include <__functional/identity.h>
+#include <__iterator/advance.h>
+#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_callable.h>
#include <__utility/pair.h>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -21,31 +27,43 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
-pair<_ForwardIterator1, _ForwardIterator1>
- _LIBCPP_CONSTEXPR_AFTER_CXX11 __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
- _ForwardIterator2 __first2, _ForwardIterator2 __last2,
- _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) {
+template <class _AlgPolicy,
+ class _Iter1, class _Sent1,
+ class _Iter2, class _Sent2,
+ class _Pred,
+ class _Proj1,
+ class _Proj2>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Pred& __pred,
+ _Proj1& __proj1,
+ _Proj2& __proj2) {
if (__first2 == __last2)
- return _VSTD::make_pair(__first1, __first1); // Everything matches an empty sequence
+ return std::make_pair(__first1, __first1); // Everything matches an empty sequence
while (true) {
// Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks
while (true) {
- if (__first1 == __last1) // return __last1 if no element matches *__first2
- return _VSTD::make_pair(__last1, __last1);
- if (__pred(*__first1, *__first2))
+ if (__first1 == __last1) { // return __last1 if no element matches *__first2
+ _IterOps<_AlgPolicy>::__advance_to(__first1, __last1);
+ return std::make_pair(__first1, __first1);
+ }
+ if (std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
break;
++__first1;
}
// *__first1 matches *__first2, now match elements after here
- _ForwardIterator1 __m1 = __first1;
- _ForwardIterator2 __m2 = __first2;
+ _Iter1 __m1 = __first1;
+ _Iter2 __m2 = __first2;
while (true) {
if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern)
- return _VSTD::make_pair(__first1, __m1);
- if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found
- return _VSTD::make_pair(__last1, __last1);
- if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1
+ return std::make_pair(__first1, ++__m1);
+ if (++__m1 == __last1) { // Otherwise if source exhaused, pattern not found
+ return std::make_pair(__m1, __m1);
+ }
+
+ // if there is a mismatch, restart with a new __first1
+ if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2)))
{
++__first1;
break;
@@ -54,38 +72,42 @@ pair<_ForwardIterator1, _ForwardIterator1>
}
}
-template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 pair<_RandomAccessIterator1, _RandomAccessIterator1>
-__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
- _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag,
- random_access_iterator_tag) {
- typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1;
- typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2;
- // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
- const _D2 __len2 = __last2 - __first2;
- if (__len2 == 0)
- return _VSTD::make_pair(__first1, __first1);
- const _D1 __len1 = __last1 - __first1;
- if (__len1 < __len2)
- return _VSTD::make_pair(__last1, __last1);
- const _RandomAccessIterator1 __s = __last1 - _D1(__len2 - 1); // Start of pattern match can't go beyond here
+template <class _AlgPolicy,
+ class _Iter1, class _Sent1,
+ class _Iter2, class _Sent2,
+ class _Pred,
+ class _Proj1,
+ class _Proj2,
+ class _DiffT1,
+ class _DiffT2>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Iter1, _Iter1> __search_random_access_impl(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Pred& __pred,
+ _Proj1& __proj1,
+ _Proj2& __proj2,
+ _DiffT1 __size1,
+ _DiffT2 __size2) {
+ const _Iter1 __s = __first1 + __size1 - _DiffT1(__size2 - 1); // Start of pattern match can't go beyond here
while (true) {
while (true) {
- if (__first1 == __s)
- return _VSTD::make_pair(__last1, __last1);
- if (__pred(*__first1, *__first2))
+ if (__first1 == __s) {
+ _IterOps<_AlgPolicy>::__advance_to(__first1, __last1);
+ return std::make_pair(__first1, __first1);
+ }
+ if (std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
break;
++__first1;
}
- _RandomAccessIterator1 __m1 = __first1;
- _RandomAccessIterator2 __m2 = __first2;
+ _Iter1 __m1 = __first1;
+ _Iter2 __m2 = __first2;
while (true) {
if (++__m2 == __last2)
- return _VSTD::make_pair(__first1, __first1 + _D1(__len2));
+ return std::make_pair(__first1, __first1 + _DiffT1(__size2));
++__m1; // no need to check range on __m1 because __s guarantees we have enough source
- if (!__pred(*__m1, *__m2)) {
+ if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) {
++__first1;
break;
}
@@ -93,22 +115,78 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _Rando
}
}
+template <class _Iter1, class _Sent1,
+ class _Iter2, class _Sent2,
+ class _Pred,
+ class _Proj1,
+ class _Proj2>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Pred& __pred,
+ _Proj1& __proj1,
+ _Proj2& __proj2,
+ __enable_if_t<__is_cpp17_random_access_iterator<_Iter1>::value
+ && __is_cpp17_random_access_iterator<_Iter2>::value>* = nullptr) {
+
+ auto __size2 = __last2 - __first2;
+ if (__size2 == 0)
+ return std::make_pair(__first1, __first1);
+
+ auto __size1 = __last1 - __first1;
+ if (__size1 < __size2) {
+ return std::make_pair(__last1, __last1);
+ }
+
+ return std::__search_random_access_impl<_ClassicAlgPolicy>(__first1, __last1,
+ __first2, __last2,
+ __pred,
+ __proj1,
+ __proj2,
+ __size1,
+ __size2);
+}
+
+template <class _Iter1, class _Sent1,
+ class _Iter2, class _Sent2,
+ class _Pred,
+ class _Proj1,
+ class _Proj2>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Pred& __pred,
+ _Proj1& __proj1,
+ _Proj2& __proj2,
+ __enable_if_t<__is_cpp17_forward_iterator<_Iter1>::value
+ && __is_cpp17_forward_iterator<_Iter2>::value
+ && !(__is_cpp17_random_access_iterator<_Iter1>::value
+ && __is_cpp17_random_access_iterator<_Iter2>::value)>* = nullptr) {
+ return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1,
+ __first2, __last2,
+ __pred,
+ __proj1,
+ __proj2);
+}
+
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
-search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2,
- _BinaryPredicate __pred) {
- return _VSTD::__search<_BinaryPredicate&>(
- __first1, __last1, __first2, __last2, __pred,
- typename iterator_traits<_ForwardIterator1>::iterator_category(),
- typename iterator_traits<_ForwardIterator2>::iterator_category()).first;
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+ _BinaryPredicate __pred) {
+ static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value,
+ "BinaryPredicate has to be callable");
+ auto __proj = __identity();
+ return std::__search_impl(__first1, __last1, __first2, __last2, __pred, __proj, __proj).first;
}
template <class _ForwardIterator1, class _ForwardIterator2>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1
-search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
- typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
- typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
- return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
+ using __v1 = typename iterator_traits<_ForwardIterator1>::value_type;
+ using __v2 = typename iterator_traits<_ForwardIterator2>::value_type;
+ return std::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
}
#if _LIBCPP_STD_VER > 14
diff --git a/libcxx/include/__algorithm/search_n.h b/libcxx/include/__algorithm/search_n.h
index 4c083de65ee2..2a0547565ee9 100644
--- a/libcxx/include/__algorithm/search_n.h
+++ b/libcxx/include/__algorithm/search_n.h
@@ -11,8 +11,15 @@
#define _LIBCPP___ALGORITHM_SEARCH_N_H
#include <__algorithm/comp.h>
+#include <__algorithm/iterator_operations.h>
#include <__config>
+#include <__functional/identity.h>
+#include <__iterator/advance.h>
+#include <__iterator/concepts.h>
+#include <__iterator/distance.h>
#include <__iterator/iterator_traits.h>
+#include <__ranges/concepts.h>
+#include <__utility/pair.h>
#include <type_traits> // __convert_to_integral
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -21,30 +28,39 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _BinaryPredicate, class _ForwardIterator, class _Size, class _Tp>
-_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator __search_n(_ForwardIterator __first, _ForwardIterator __last,
- _Size __count, const _Tp& __value_, _BinaryPredicate __pred,
- forward_iterator_tag) {
+template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last,
+ _SizeT __count,
+ const _Type& __value,
+ _Pred& __pred,
+ _Proj& __proj) {
if (__count <= 0)
- return __first;
+ return std::make_pair(__first, __first);
while (true) {
- // Find first element in sequence that matchs __value_, with a mininum of loop checks
+ // Find first element in sequence that matchs __value, with a mininum of loop checks
while (true) {
- if (__first == __last) // return __last if no element matches __value_
- return __last;
- if (__pred(*__first, __value_))
+ if (__first == __last) { // return __last if no element matches __value
+ _IterOps<_AlgPolicy>::__advance_to(__first, __last);
+ return std::make_pair(__first, __first);
+ }
+ if (std::__invoke(__pred, std::__invoke(__proj, *__first), __value))
break;
++__first;
}
- // *__first matches __value_, now match elements after here
- _ForwardIterator __m = __first;
- _Size __c(0);
+ // *__first matches __value, now match elements after here
+ _Iter __m = __first;
+ _SizeT __c(0);
while (true) {
if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern)
- return __first;
- if (++__m == __last) // Otherwise if source exhaused, pattern not found
- return __last;
- if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first
+ return std::make_pair(__first, ++__m);
+ if (++__m == __last) { // Otherwise if source exhaused, pattern not found
+ _IterOps<_AlgPolicy>::__advance_to(__first, __last);
+ return std::make_pair(__first, __first);
+ }
+
+ // if there is a mismatch, restart with a new __first
+ if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value))
{
__first = __m;
++__first;
@@ -54,35 +70,44 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator __search_n(_ForwardIterator __fir
}
}
-template <class _BinaryPredicate, class _RandomAccessIterator, class _Size, class _Tp>
-_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator __search_n(_RandomAccessIterator __first,
- _RandomAccessIterator __last, _Size __count,
- const _Tp& __value_, _BinaryPredicate __pred,
- random_access_iterator_tag) {
- typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
- if (__count <= 0)
- return __first;
- _Size __len = static_cast<_Size>(__last - __first);
- if (__len < __count)
- return __last;
- const _RandomAccessIterator __s = __last - difference_type(__count - 1); // Start of pattern match can't go beyond here
+template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj, class _DiffT>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __last,
+ _SizeT __count,
+ const _Type& __value,
+ _Pred& __pred,
+ _Proj& __proj,
+ _DiffT __size1) {
+ using difference_type = typename iterator_traits<_Iter>::difference_type;
+ if (__count == 0)
+ return std::make_pair(__first, __first);
+ if (__size1 < static_cast<_DiffT>(__count)) {
+ _IterOps<_AlgPolicy>::__advance_to(__first, __last);
+ return std::make_pair(__first, __first);
+ }
+
+ const auto __s = __first + __size1 - difference_type(__count - 1); // Start of pattern match can't go beyond here
while (true) {
- // Find first element in sequence that matchs __value_, with a mininum of loop checks
+ // Find first element in sequence that matchs __value, with a mininum of loop checks
while (true) {
- if (__first >= __s) // return __last if no element matches __value_
- return __last;
- if (__pred(*__first, __value_))
+ if (__first >= __s) { // return __last if no element matches __value
+ _IterOps<_AlgPolicy>::__advance_to(__first, __last);
+ return std::make_pair(__first, __first);
+ }
+ if (std::__invoke(__pred, std::__invoke(__proj, *__first), __value))
break;
++__first;
}
// *__first matches __value_, now match elements after here
- _RandomAccessIterator __m = __first;
- _Size __c(0);
+ auto __m = __first;
+ _SizeT __c(0);
while (true) {
if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern)
- return __first;
- ++__m; // no need to check range on __m because __s guarantees we have enough source
- if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first
+ return std::make_pair(__first, __first + _DiffT(__count));
+ ++__m; // no need to check range on __m because __s guarantees we have enough source
+
+ // if there is a mismatch, restart with a new __first
+ if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value))
{
__first = __m;
++__first;
@@ -92,19 +117,63 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator __search_n(_RandomAccessIter
}
}
+template <class _Iter, class _Sent,
+ class _DiffT,
+ class _Type,
+ class _Pred,
+ class _Proj>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Iter, _Iter> __search_n_impl(_Iter __first, _Sent __last,
+ _DiffT __count,
+ const _Type& __value,
+ _Pred& __pred,
+ _Proj& __proj,
+ __enable_if_t<__is_cpp17_random_access_iterator<_Iter>::value>* = nullptr) {
+ return std::__search_n_random_access_impl<_ClassicAlgPolicy>(__first, __last,
+ __count,
+ __value,
+ __pred,
+ __proj,
+ __last - __first);
+}
+
+template <class _Iter1, class _Sent1,
+ class _DiffT,
+ class _Type,
+ class _Pred,
+ class _Proj>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Iter1, _Iter1> __search_n_impl(_Iter1 __first, _Sent1 __last,
+ _DiffT __count,
+ const _Type& __value,
+ _Pred& __pred,
+ _Proj& __proj,
+ __enable_if_t<__is_cpp17_forward_iterator<_Iter1>::value
+ && !__is_cpp17_random_access_iterator<_Iter1>::value>* = nullptr) {
+ return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last,
+ __count,
+ __value,
+ __pred,
+ __proj);
+}
+
template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator search_n(
- _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_, _BinaryPredicate __pred) {
- return _VSTD::__search_n<_BinaryPredicate&>(
- __first, __last, _VSTD::__convert_to_integral(__count), __value_, __pred,
- typename iterator_traits<_ForwardIterator>::iterator_category());
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last,
+ _Size __count,
+ const _Tp& __value,
+ _BinaryPredicate __pred) {
+ static_assert(__is_callable<_BinaryPredicate, decltype(*__first), decltype(*__last)>::value,
+ "BinaryPredicate has to be callable");
+ auto __proj = __identity();
+ return std::__search_n_impl(__first, __last, std::__convert_to_integral(__count), __value, __pred, __proj).first;
}
template <class _ForwardIterator, class _Size, class _Tp>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
-search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_) {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) {
typedef typename iterator_traits<_ForwardIterator>::value_type __v;
- return _VSTD::search_n(__first, __last, _VSTD::__convert_to_integral(__count), __value_, __equal_to<__v, _Tp>());
+ return std::search_n(__first, __last, std::__convert_to_integral(__count), __value, __equal_to<__v, _Tp>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/set_difference.h b/libcxx/include/__algorithm/set_difference.h
index 5e2dca24e446..4378bd5304d9 100644
--- a/libcxx/include/__algorithm/set_difference.h
+++ b/libcxx/include/__algorithm/set_difference.h
@@ -13,7 +13,12 @@
#include <__algorithm/comp_ref_type.h>
#include <__algorithm/copy.h>
#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
#include <__iterator/iterator_traits.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -21,50 +26,52 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
-__set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
- _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
- while (__first1 != __last1)
- {
- if (__first2 == __last2)
- return _VSTD::copy(__first1, __last1, __result);
- if (__comp(*__first1, *__first2))
- {
- *__result = *__first1;
- ++__result;
- ++__first1;
- }
- else
- {
- if (!__comp(*__first2, *__first1))
- ++__first1;
- ++__first2;
- }
+template < class _Comp, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<__uncvref_t<_InIter1>, __uncvref_t<_OutIter> >
+__set_difference(
+ _InIter1&& __first1, _Sent1&& __last1, _InIter2&& __first2, _Sent2&& __last2, _OutIter&& __result, _Comp&& __comp) {
+ while (__first1 != __last1 && __first2 != __last2) {
+ if (__comp(*__first1, *__first2)) {
+ *__result = *__first1;
+ ++__first1;
+ ++__result;
+ } else if (__comp(*__first2, *__first1)) {
+ ++__first2;
+ } else {
+ ++__first1;
+ ++__first2;
}
- return __result;
+ }
+ return std::__copy(std::move(__first1), std::move(__last1), std::move(__result));
}
template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-_OutputIterator
-set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
- _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
- typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
- return _VSTD::__set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_difference(
+ _InputIterator1 __first1,
+ _InputIterator1 __last1,
+ _InputIterator2 __first2,
+ _InputIterator2 __last2,
+ _OutputIterator __result,
+ _Compare __comp) {
+ typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+ return std::__set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp).second;
}
template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-_OutputIterator
-set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
- _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
-{
- return _VSTD::set_difference(__first1, __last1, __first2, __last2, __result,
- __less<typename iterator_traits<_InputIterator1>::value_type,
- typename iterator_traits<_InputIterator2>::value_type>());
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_difference(
+ _InputIterator1 __first1,
+ _InputIterator1 __last1,
+ _InputIterator2 __first2,
+ _InputIterator2 __last2,
+ _OutputIterator __result) {
+ return std::__set_difference(
+ __first1,
+ __last1,
+ __first2,
+ __last2,
+ __result,
+ __less<typename iterator_traits<_InputIterator1>::value_type,
+ typename iterator_traits<_InputIterator2>::value_type>()).second;
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/set_intersection.h b/libcxx/include/__algorithm/set_intersection.h
index c4163fcd4c3c..77cc83738d1f 100644
--- a/libcxx/include/__algorithm/set_intersection.h
+++ b/libcxx/include/__algorithm/set_intersection.h
@@ -11,8 +11,11 @@
#include <__algorithm/comp.h>
#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/iterator_operations.h>
#include <__config>
#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -20,48 +23,76 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
-__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
- _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
- while (__first1 != __last1 && __first2 != __last2)
- {
- if (__comp(*__first1, *__first2))
- ++__first1;
- else
- {
- if (!__comp(*__first2, *__first1))
- {
- *__result = *__first1;
- ++__result;
- ++__first1;
- }
- ++__first2;
- }
+template <class _InIter1, class _InIter2, class _OutIter>
+struct __set_intersection_result {
+ _InIter1 __in1_;
+ _InIter2 __in2_;
+ _OutIter __out_;
+
+ // need a constructor as C++03 aggregate init is hard
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ __set_intersection_result(_InIter1&& __in_iter1, _InIter2&& __in_iter2, _OutIter&& __out_iter)
+ : __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {}
+};
+
+template <class _AlgPolicy, class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 __set_intersection_result<_InIter1, _InIter2, _OutIter>
+__set_intersection(
+ _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) {
+ while (__first1 != __last1 && __first2 != __last2) {
+ if (__comp(*__first1, *__first2))
+ ++__first1;
+ else {
+ if (!__comp(*__first2, *__first1)) {
+ *__result = *__first1;
+ ++__result;
+ ++__first1;
+ }
+ ++__first2;
}
- return __result;
+ }
+
+ return __set_intersection_result<_InIter1, _InIter2, _OutIter>(
+ _IterOps<_AlgPolicy>::next(std::move(__first1), std::move(__last1)),
+ _IterOps<_AlgPolicy>::next(std::move(__first2), std::move(__last2)),
+ std::move(__result));
}
template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-_OutputIterator
-set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
- _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
- typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
- return _VSTD::__set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_intersection(
+ _InputIterator1 __first1,
+ _InputIterator1 __last1,
+ _InputIterator2 __first2,
+ _InputIterator2 __last2,
+ _OutputIterator __result,
+ _Compare __comp) {
+ typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+ return std::__set_intersection<_ClassicAlgPolicy, _Comp_ref>(
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::move(__result),
+ __comp)
+ .__out_;
}
template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-_OutputIterator
-set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
- _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
-{
- return _VSTD::set_intersection(__first1, __last1, __first2, __last2, __result,
- __less<typename iterator_traits<_InputIterator1>::value_type,
- typename iterator_traits<_InputIterator2>::value_type>());
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_intersection(
+ _InputIterator1 __first1,
+ _InputIterator1 __last1,
+ _InputIterator2 __first2,
+ _InputIterator2 __last2,
+ _OutputIterator __result) {
+ return std::__set_intersection<_ClassicAlgPolicy>(
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::move(__result),
+ __less<typename iterator_traits<_InputIterator1>::value_type,
+ typename iterator_traits<_InputIterator2>::value_type>())
+ .__out_;
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/set_symmetric_difference.h b/libcxx/include/__algorithm/set_symmetric_difference.h
index 2dbfb35d7be6..cd532ab5800d 100644
--- a/libcxx/include/__algorithm/set_symmetric_difference.h
+++ b/libcxx/include/__algorithm/set_symmetric_difference.h
@@ -14,6 +14,7 @@
#include <__algorithm/copy.h>
#include <__config>
#include <__iterator/iterator_traits.h>
+#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -21,55 +22,81 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator
-__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
- _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
- while (__first1 != __last1)
- {
- if (__first2 == __last2)
- return _VSTD::copy(__first1, __last1, __result);
- if (__comp(*__first1, *__first2))
- {
- *__result = *__first1;
- ++__result;
- ++__first1;
- }
- else
- {
- if (__comp(*__first2, *__first1))
- {
- *__result = *__first2;
- ++__result;
- }
- else
- ++__first1;
- ++__first2;
- }
+template <class _InIter1, class _InIter2, class _OutIter>
+struct __set_symmetric_difference_result {
+ _InIter1 __in1_;
+ _InIter2 __in2_;
+ _OutIter __out_;
+
+ // need a constructor as C++03 aggregate init is hard
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+ __set_symmetric_difference_result(_InIter1&& __in_iter1, _InIter2&& __in_iter2, _OutIter&& __out_iter)
+ : __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {}
+};
+
+template <class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 __set_symmetric_difference_result<_InIter1, _InIter2, _OutIter>
+__set_symmetric_difference(
+ _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) {
+ while (__first1 != __last1) {
+ if (__first2 == __last2) {
+ auto __ret1 = std::__copy_impl(std::move(__first1), std::move(__last1), std::move(__result));
+ return __set_symmetric_difference_result<_InIter1, _InIter2, _OutIter>(
+ std::move(__ret1.first), std::move(__first2), std::move((__ret1.second)));
+ }
+ if (__comp(*__first1, *__first2)) {
+ *__result = *__first1;
+ ++__result;
+ ++__first1;
+ } else {
+ if (__comp(*__first2, *__first1)) {
+ *__result = *__first2;
+ ++__result;
+ } else {
+ ++__first1;
+ }
+ ++__first2;
}
- return _VSTD::copy(__first2, __last2, __result);
+ }
+ auto __ret2 = std::__copy_impl(std::move(__first2), std::move(__last2), std::move(__result));
+ return __set_symmetric_difference_result<_InIter1, _InIter2, _OutIter>(
+ std::move(__first1), std::move(__ret2.first), std::move((__ret2.second)));
}
template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-_OutputIterator
-set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
- _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
-{
- typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
- return _VSTD::__set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_symmetric_difference(
+ _InputIterator1 __first1,
+ _InputIterator1 __last1,
+ _InputIterator2 __first2,
+ _InputIterator2 __last2,
+ _OutputIterator __result,
+ _Compare __comp) {
+ typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
+ return std::__set_symmetric_difference<_Comp_ref>(
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::move(__result),
+ __comp)
+ .__out_;
}
template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-_OutputIterator
-set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
- _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
-{
- return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result,
- __less<typename iterator_traits<_InputIterator1>::value_type,
- typename iterator_traits<_InputIterator2>::value_type>());
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_symmetric_difference(
+ _InputIterator1 __first1,
+ _InputIterator1 __last1,
+ _InputIterator2 __first2,
+ _InputIterator2 __last2,
+ _OutputIterator __result) {
+ return std::set_symmetric_difference(
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::move(__result),
+ __less<typename iterator_traits<_InputIterator1>::value_type,
+ typename iterator_traits<_InputIterator2>::value_type>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/sort.h b/libcxx/include/__algorithm/sort.h
index f7406a5170e1..76a18215731b 100644
--- a/libcxx/include/__algorithm/sort.h
+++ b/libcxx/include/__algorithm/sort.h
@@ -17,6 +17,7 @@
#include <__bits>
#include <__config>
#include <__debug>
+#include <__debug_utils/randomize_range.h>
#include <__functional/operations.h>
#include <__functional/ranges_operations.h>
#include <__iterator/iterator_traits.h>
@@ -24,10 +25,6 @@
#include <climits>
#include <memory>
-#if defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY)
-# include <__algorithm/shuffle.h>
-#endif
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
@@ -582,7 +579,7 @@ extern template _LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long dou
template <class _RandomAccessIterator, class _Comp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
- _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __last);
+ std::__debug_randomize_range(__first, __last);
using _Comp_ref = typename __comp_ref_type<_Comp>::type;
if (__libcpp_is_constant_evaluated()) {
std::__partial_sort<_Comp_ref>(__first, __last, __last, _Comp_ref(__comp));
diff --git a/libcxx/include/__algorithm/sort_heap.h b/libcxx/include/__algorithm/sort_heap.h
index 3a63d744fc1c..261adedd0eaf 100644
--- a/libcxx/include/__algorithm/sort_heap.h
+++ b/libcxx/include/__algorithm/sort_heap.h
@@ -14,6 +14,7 @@
#include <__algorithm/pop_heap.h>
#include <__config>
#include <__iterator/iterator_traits.h>
+#include <__utility/move.h>
#include <type_traits> // swap
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -23,29 +24,27 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Compare, class _RandomAccessIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX17 void
-__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
- typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
- for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n)
- _VSTD::__pop_heap<_Compare>(__first, __last, __comp, __n);
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
+ using _CompRef = typename __comp_ref_type<_Compare>::type;
+ _CompRef __comp_ref = __comp;
+
+ using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
+ for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n)
+ std::__pop_heap<_CompRef>(__first, __last, __comp_ref, __n);
}
template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-void
-sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
-{
- typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
- _VSTD::__sort_heap<_Comp_ref>(__first, __last, __comp);
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+ std::__sort_heap(std::move(__first), std::move(__last), __comp);
}
template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-void
-sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
-{
- _VSTD::sort_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
+ std::sort_heap(std::move(__first), std::move(__last),
+ __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/upper_bound.h b/libcxx/include/__algorithm/upper_bound.h
index c6483607e3c6..3fc254873532 100644
--- a/libcxx/include/__algorithm/upper_bound.h
+++ b/libcxx/include/__algorithm/upper_bound.h
@@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Compare, class _ForwardIterator, class _Tp>
_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
-__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp)
{
typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
difference_type __len = _VSTD::distance(__first, __last);
@@ -33,7 +33,7 @@ __upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va
difference_type __l2 = _VSTD::__half_positive(__len);
_ForwardIterator __m = __first;
_VSTD::advance(__m, __l2);
- if (__comp(__value_, *__m))
+ if (__comp(__value, *__m))
__len = __l2;
else
{
@@ -48,18 +48,18 @@ template <class _ForwardIterator, class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_ForwardIterator
-upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp)
{
- return _VSTD::__upper_bound<_Compare&>(__first, __last, __value_, __comp);
+ return _VSTD::__upper_bound<_Compare&>(__first, __last, __value, __comp);
}
template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_ForwardIterator
-upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
{
- return _VSTD::upper_bound(__first, __last, __value_,
+ return _VSTD::upper_bound(__first, __last, __value,
__less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>());
}
diff --git a/libcxx/include/__bit_reference b/libcxx/include/__bit_reference
index 8c4f1badbd35..f54cb6c16f48 100644
--- a/libcxx/include/__bit_reference
+++ b/libcxx/include/__bit_reference
@@ -250,9 +250,9 @@ __find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type
template <class _Cp, bool _IsConst, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
__bit_iterator<_Cp, _IsConst>
-find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
+find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value)
{
- if (static_cast<bool>(__value_))
+ if (static_cast<bool>(__value))
return _VSTD::__find_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
return _VSTD::__find_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
}
@@ -324,9 +324,9 @@ __count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_typ
template <class _Cp, bool _IsConst, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
typename __bit_iterator<_Cp, _IsConst>::difference_type
-count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
+count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value)
{
- if (static_cast<bool>(__value_))
+ if (static_cast<bool>(__value))
return _VSTD::__count_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
return _VSTD::__count_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
}
@@ -396,11 +396,11 @@ __fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
template <class _Cp>
inline _LIBCPP_INLINE_VISIBILITY
void
-fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value_)
+fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value)
{
if (__n > 0)
{
- if (__value_)
+ if (__value)
_VSTD::__fill_n_true(__first, __n);
else
_VSTD::__fill_n_false(__first, __n);
@@ -412,9 +412,9 @@ fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __v
template <class _Cp>
inline _LIBCPP_INLINE_VISIBILITY
void
-fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value_)
+fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value)
{
- _VSTD::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value_);
+ _VSTD::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value);
}
// copy
diff --git a/libcxx/include/__bits b/libcxx/include/__bits
index 1eee8f576e9e..92ef5c0a7b49 100644
--- a/libcxx/include/__bits
+++ b/libcxx/include/__bits
@@ -43,6 +43,23 @@ int __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x);
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); }
+# ifndef _LIBCPP_HAS_NO_INT128
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_clz(__uint128_t __x) _NOEXCEPT {
+ // The function is written in this form due to C++ constexpr limitations.
+ // The algorithm:
+ // - Test whether any bit in the high 64-bits is set
+ // - No bits set:
+ // - The high 64-bits contain 64 leading zeros,
+ // - Add the result of the low 64-bits.
+ // - Any bits set:
+ // - The number of leading zeros of the input is the number of leading
+ // zeros in the high 64-bits.
+ return ((__x >> 64) == 0)
+ ? (64 + __builtin_clzll(static_cast<unsigned long long>(__x)))
+ : __builtin_clzll(static_cast<unsigned long long>(__x >> 64));
+}
+# endif
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
int __libcpp_popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); }
diff --git a/libcxx/include/__charconv/tables.h b/libcxx/include/__charconv/tables.h
index a2f7f7ce29b3..83f39e6fd2ef 100644
--- a/libcxx/include/__charconv/tables.h
+++ b/libcxx/include/__charconv/tables.h
@@ -35,6 +35,11 @@ struct __table {
static const uint32_t __pow10_32[10];
static const uint64_t __pow10_64[20];
+# ifndef _LIBCPP_HAS_NO_INT128
+ // TODO FMT Reduce the number of entries in this table.
+ static const __uint128_t __pow10_128[40];
+ static const int __pow10_128_offset = 0;
+# endif
static const char __digits_base_10[200];
};
@@ -106,6 +111,51 @@ const uint64_t __table<_Tp>::__pow10_64[20] = {UINT64_C(0),
UINT64_C(1000000000000000000),
UINT64_C(10000000000000000000)};
+# ifndef _LIBCPP_HAS_NO_INT128
+template <class _Tp>
+const __uint128_t __table<_Tp>::__pow10_128[40] = {
+ UINT64_C(0),
+ UINT64_C(10),
+ UINT64_C(100),
+ UINT64_C(1000),
+ UINT64_C(10000),
+ UINT64_C(100000),
+ UINT64_C(1000000),
+ UINT64_C(10000000),
+ UINT64_C(100000000),
+ UINT64_C(1000000000),
+ UINT64_C(10000000000),
+ UINT64_C(100000000000),
+ UINT64_C(1000000000000),
+ UINT64_C(10000000000000),
+ UINT64_C(100000000000000),
+ UINT64_C(1000000000000000),
+ UINT64_C(10000000000000000),
+ UINT64_C(100000000000000000),
+ UINT64_C(1000000000000000000),
+ UINT64_C(10000000000000000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000000000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000000000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000000000000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000000000000000),
+ __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000000000000),
+ (__uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000000000000)) * 10};
+# endif
+
template <class _Tp>
const char __table<_Tp>::__digits_base_10[200] = {
// clang-format off
diff --git a/libcxx/include/__charconv/to_chars_base_10.h b/libcxx/include/__charconv/to_chars_base_10.h
index 91c209559aff..d25deffc592f 100644
--- a/libcxx/include/__charconv/to_chars_base_10.h
+++ b/libcxx/include/__charconv/to_chars_base_10.h
@@ -14,11 +14,15 @@
#include <__charconv/tables.h>
#include <__config>
#include <cstdint>
+#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
#ifndef _LIBCPP_CXX03_LANG
@@ -62,7 +66,6 @@ _LIBCPP_HIDE_FROM_ABI inline char* __append9(char* __first, uint32_t __value) no
return __itoa::__append8(__itoa::__append1(__first, __value / 100000000), __value % 100000000);
}
-// This function is used for uint32_t and uint64_t.
template <class _Tp>
_LIBCPP_HIDE_FROM_ABI char* __append10(char* __first, _Tp __value) noexcept {
return __itoa::__append8(__itoa::__append2(__first, static_cast<uint32_t>(__value / 100000000)),
@@ -118,10 +121,65 @@ _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u64(char* __buffer, uint64_t __valu
return __itoa::__append10(__buffer, __value);
}
+# ifndef _LIBCPP_HAS_NO_INT128
+/// \returns 10^\a exp
+///
+/// \pre \a exp [19, 39]
+///
+/// \note The lookup table contains a partial set of exponents limiting the
+/// range that can be used. However the range is sufficient for
+/// \ref __base_10_u128.
+_LIBCPP_HIDE_FROM_ABI inline __uint128_t __pow_10(int __exp) noexcept {
+ _LIBCPP_ASSERT(__exp >= __table<>::__pow10_128_offset, "Index out of bounds");
+ return __table<>::__pow10_128[__exp - __table<>::__pow10_128_offset];
+}
+
+_LIBCPP_HIDE_FROM_ABI inline char* __base_10_u128(char* __buffer, __uint128_t __value) noexcept {
+ _LIBCPP_ASSERT(
+ __value > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true.");
+
+ // Unlike the 64 to 32 bit case the 128 bit case the "upper half" can't be
+ // stored in the "lower half". Instead we first need to handle the top most
+ // digits separately.
+ //
+ // Maximum unsigned values
+ // 64 bit 18'446'744'073'709'551'615 (20 digits)
+ // 128 bit 340'282'366'920'938'463'463'374'607'431'768'211'455 (39 digits)
+ // step 1 ^ ([0-1] digits)
+ // step 2 ^^^^^^^^^^^^^^^^^^^^^^^^^ ([0-19] digits)
+ // step 3 ^^^^^^^^^^^^^^^^^^^^^^^^^ (19 digits)
+ if (__value >= __itoa::__pow_10(38)) {
+ // step 1
+ __buffer = __itoa::__append1(__buffer, static_cast<uint32_t>(__value / __itoa::__pow_10(38)));
+ __value %= __itoa::__pow_10(38);
+
+ // step 2 always 19 digits.
+ // They are handled here since leading zeros need to be appended to the buffer,
+ __buffer = __itoa::__append9(__buffer, static_cast<uint32_t>(__value / __itoa::__pow_10(29)));
+ __value %= __itoa::__pow_10(29);
+ __buffer = __itoa::__append10(__buffer, static_cast<uint64_t>(__value / __itoa::__pow_10(19)));
+ __value %= __itoa::__pow_10(19);
+ }
+ else {
+ // step 2
+ // This version needs to determine the position of the leading non-zero digit.
+ __buffer = __base_10_u64(__buffer, static_cast<uint64_t>(__value / __itoa::__pow_10(19)));
+ __value %= __itoa::__pow_10(19);
+ }
+
+ // Step 3
+ __buffer = __itoa::__append9(__buffer, static_cast<uint32_t>(__value / 10000000000));
+ __buffer = __itoa::__append10(__buffer, static_cast<uint64_t>(__value % 10000000000));
+
+ return __buffer;
+}
+# endif
} // namespace __itoa
#endif // _LIBCPP_CXX03_LANG
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H
diff --git a/libcxx/include/__chrono/day.h b/libcxx/include/__chrono/day.h
index 7e425558e359..d9fa4ffbc45e 100644
--- a/libcxx/include/__chrono/day.h
+++ b/libcxx/include/__chrono/day.h
@@ -12,6 +12,7 @@
#include <__chrono/duration.h>
#include <__config>
+#include <compare>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -45,25 +46,9 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
bool operator==(const day& __lhs, const day& __rhs) noexcept
{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
-_LIBCPP_HIDE_FROM_ABI inline constexpr
-bool operator!=(const day& __lhs, const day& __rhs) noexcept
-{ return !(__lhs == __rhs); }
-
-_LIBCPP_HIDE_FROM_ABI inline constexpr
-bool operator< (const day& __lhs, const day& __rhs) noexcept
-{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); }
-
-_LIBCPP_HIDE_FROM_ABI inline constexpr
-bool operator> (const day& __lhs, const day& __rhs) noexcept
-{ return __rhs < __lhs; }
-
-_LIBCPP_HIDE_FROM_ABI inline constexpr
-bool operator<=(const day& __lhs, const day& __rhs) noexcept
-{ return !(__rhs < __lhs);}
-
-_LIBCPP_HIDE_FROM_ABI inline constexpr
-bool operator>=(const day& __lhs, const day& __rhs) noexcept
-{ return !(__lhs < __rhs); }
+_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const day& __lhs, const day& __rhs) noexcept {
+ return static_cast<unsigned>(__lhs) <=> static_cast<unsigned>(__rhs);
+}
_LIBCPP_HIDE_FROM_ABI inline constexpr
day operator+ (const day& __lhs, const days& __rhs) noexcept
diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h
index f5207594291e..c502574fb267 100644
--- a/libcxx/include/__chrono/duration.h
+++ b/libcxx/include/__chrono/duration.h
@@ -286,10 +286,10 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator*=(const rep& rhs) {__rep_ *= rhs; return *this;}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator/=(const rep& rhs) {__rep_ /= rhs; return *this;}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const rep& rhs) {__rep_ %= rhs; return *this;}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const duration& rhs) {__rep_ %= rhs.count(); return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator*=(const rep& __rhs) {__rep_ *= __rhs; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator/=(const rep& __rhs) {__rep_ /= __rhs; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const rep& __rhs) {__rep_ %= __rhs; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const duration& __rhs) {__rep_ %= __rhs.count(); return *this;}
// special values
diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h
index ac2d347a0dca..63d67d77dd05 100644
--- a/libcxx/include/__chrono/time_point.h
+++ b/libcxx/include/__chrono/time_point.h
@@ -47,12 +47,12 @@ public:
// conversions
template <class _Duration2>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
- time_point(const time_point<clock, _Duration2>& t,
+ time_point(const time_point<clock, _Duration2>& __t,
typename enable_if
<
is_convertible<_Duration2, duration>::value
>::type* = nullptr)
- : __d_(t.time_since_epoch()) {}
+ : __d_(__t.time_since_epoch()) {}
// observer
diff --git a/libcxx/include/__chrono/year.h b/libcxx/include/__chrono/year.h
index a641fe1c93b0..c7f0027eba7b 100644
--- a/libcxx/include/__chrono/year.h
+++ b/libcxx/include/__chrono/year.h
@@ -12,6 +12,7 @@
#include <__chrono/duration.h>
#include <__config>
+#include <limits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -100,9 +101,11 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr
year& year::operator-=(const years& __dy) noexcept
{ *this = *this - __dy; return *this; }
-_LIBCPP_HIDE_FROM_ABI inline constexpr
-bool year::ok() const noexcept
-{ return static_cast<int>(min()) <= __y && __y <= static_cast<int>(max()); }
+_LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept {
+ static_assert(static_cast<int>(std::numeric_limits<decltype(__y)>::max()) == static_cast<int>(max()));
+ return static_cast<int>(min()) <= __y;
+}
+
} // namespace chrono
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__chrono/year_month_weekday.h b/libcxx/include/__chrono/year_month_weekday.h
index 9ba81e7e3f65..b69b77152fb1 100644
--- a/libcxx/include/__chrono/year_month_weekday.h
+++ b/libcxx/include/__chrono/year_month_weekday.h
@@ -47,10 +47,10 @@ public:
: year_month_weekday(__from_days(__sysd.time_since_epoch())) {}
_LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept
: year_month_weekday(__from_days(__locd.time_since_epoch())) {}
- _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const months& m) noexcept;
- _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const months& m) noexcept;
- _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const years& y) noexcept;
- _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const years& y) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const months&) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const months&) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const years&) noexcept;
+ _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const years&) noexcept;
_LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y; }
_LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m; }
diff --git a/libcxx/include/__config b/libcxx/include/__config
index e4b7d25edf34..22c2ed7fd87b 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -26,6 +26,13 @@
# define _LIBCPP_VERSION 15000
+# define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
+# define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)
+
+// Valid C++ identifier that revs with every libc++ version. This can be used to
+// generate identifiers that must be unique for every released libc++ version.
+# define _LIBCPP_VERSIONED_IDENTIFIER _LIBCPP_CONCAT(v, _LIBCPP_VERSION)
+
# if __STDC_HOSTED__ == 0
# define _LIBCPP_FREESTANDING
# endif
@@ -568,12 +575,6 @@ typedef __char32_t char32_t;
# endif // defined(_LIBCPP_OBJECT_FORMAT_COFF)
-# if __has_attribute(internal_linkage)
-# define _LIBCPP_INTERNAL_LINKAGE __attribute__((internal_linkage))
-# else
-# define _LIBCPP_INTERNAL_LINKAGE _LIBCPP_ALWAYS_INLINE
-# endif
-
# if __has_attribute(exclude_from_explicit_instantiation)
# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((__exclude_from_explicit_instantiation__))
# else
@@ -583,20 +584,35 @@ typedef __char32_t char32_t;
# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE
# endif
-# ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU
-# ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT
-# define _LIBCPP_HIDE_FROM_ABI_PER_TU 0
-# else
-# define _LIBCPP_HIDE_FROM_ABI_PER_TU 1
-# endif
-# endif
-
-# ifndef _LIBCPP_HIDE_FROM_ABI
-# if _LIBCPP_HIDE_FROM_ABI_PER_TU
-# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE
-# else
-# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
-# endif
+// This macro marks a symbol as being hidden from libc++'s ABI. This is achieved
+// on two levels:
+// 1. The symbol is given hidden visibility, which ensures that users won't start exporting
+// symbols from their dynamic library by means of using the libc++ headers. This ensures
+// that those symbols stay private to the dynamic library in which it is defined.
+//
+// 2. The symbol is given an ABI tag that changes with each version of libc++. This ensures
+// that no ODR violation can arise from mixing two TUs compiled with different versions
+// of libc++ where we would have changed the definition of a symbol. If the symbols shared
+// the same name, the ODR would require that their definitions be token-by-token equivalent,
+// which basically prevents us from being able to make any change to any function in our
+// headers. Using this ABI tag ensures that the symbol name is "bumped" artificially at
+// each release, which lets us change the definition of these symbols at our leisure.
+// Note that historically, this has been achieved in various ways, including force-inlining
+// all functions or giving internal linkage to all functions. Both these (previous) solutions
+// suffer from drawbacks that lead notably to code bloat.
+//
+// Note that we use _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION to ensure that we don't depend
+// on _LIBCPP_HIDE_FROM_ABI methods of classes explicitly instantiated in the dynamic library.
+//
+// TODO: We provide a escape hatch with _LIBCPP_NO_ABI_TAG for folks who want to avoid increasing
+// the length of symbols with an ABI tag. In practice, we should remove the escape hatch and
+// use compression mangling instead, see https://github.com/itanium-cxx-abi/cxx-abi/issues/70.
+# ifndef _LIBCPP_NO_ABI_TAG
+# define _LIBCPP_HIDE_FROM_ABI \
+ _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION \
+ __attribute__((__abi_tag__(_LIBCPP_TOSTRING(_LIBCPP_VERSIONED_IDENTIFIER))))
+# else
+# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
# endif
# ifdef _LIBCPP_BUILDING_LIBRARY
diff --git a/libcxx/include/__debug b/libcxx/include/__debug
index d3dd202b54ab..59e85cb7d1bc 100644
--- a/libcxx/include/__debug
+++ b/libcxx/include/__debug
@@ -28,22 +28,6 @@
# define _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY
#endif
-// TODO: Define this as a function instead
-#if defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY)
-# if defined(_LIBCPP_CXX03_LANG)
-# error Support for unspecified stability is only for C++11 and higher
-# endif
-# define _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __last) \
- do { \
- if (!__builtin_is_constant_evaluated()) \
- std::shuffle(__first, __last, __libcpp_debug_randomizer()); \
- } while (false)
-#else
-# define _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __last) \
- do { \
- } while (false)
-#endif
-
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
# define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(::std::__libcpp_is_constant_evaluated() || (x), m)
#else
diff --git a/libcxx/include/__debug_utils/randomize_range.h b/libcxx/include/__debug_utils/randomize_range.h
new file mode 100644
index 000000000000..fd5b9e588493
--- /dev/null
+++ b/libcxx/include/__debug_utils/randomize_range.h
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___LIBCXX_DEBUG_RANDOMIZE_RANGE_H
+#define _LIBCPP___LIBCXX_DEBUG_RANDOMIZE_RANGE_H
+
+#include <__config>
+
+#ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY
+# include <__algorithm/shuffle.h>
+# include <__type_traits/is_constant_evaluated.h>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Iterator>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 void __debug_randomize_range(_Iterator __first, _Iterator __last) {
+#ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY
+# ifdef _LIBCPP_CXX03_LANG
+# error Support for unspecified stability is only for C++11 and higher
+# endif
+
+ if (!__libcpp_is_constant_evaluated())
+ std::shuffle(__first, __last, __libcpp_debug_randomizer());
+#else
+ (void)__first;
+ (void)__last;
+#endif
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___LIBCXX_DEBUG_RANDOMIZE_RANGE_H
diff --git a/libcxx/include/__filesystem/copy_options.h b/libcxx/include/__filesystem/copy_options.h
index 2e037403f6f2..96c7535812e2 100644
--- a/libcxx/include/__filesystem/copy_options.h
+++ b/libcxx/include/__filesystem/copy_options.h
@@ -38,41 +38,41 @@ enum class _LIBCPP_ENUM_VIS copy_options : unsigned short {
};
_LIBCPP_INLINE_VISIBILITY
-inline constexpr copy_options operator&(copy_options _LHS, copy_options _RHS) {
- return static_cast<copy_options>(static_cast<unsigned short>(_LHS) &
- static_cast<unsigned short>(_RHS));
+inline constexpr copy_options operator&(copy_options __lhs, copy_options __rhs) {
+ return static_cast<copy_options>(static_cast<unsigned short>(__lhs) &
+ static_cast<unsigned short>(__rhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline constexpr copy_options operator|(copy_options _LHS, copy_options _RHS) {
- return static_cast<copy_options>(static_cast<unsigned short>(_LHS) |
- static_cast<unsigned short>(_RHS));
+inline constexpr copy_options operator|(copy_options __lhs, copy_options __rhs) {
+ return static_cast<copy_options>(static_cast<unsigned short>(__lhs) |
+ static_cast<unsigned short>(__rhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline constexpr copy_options operator^(copy_options _LHS, copy_options _RHS) {
- return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^
- static_cast<unsigned short>(_RHS));
+inline constexpr copy_options operator^(copy_options __lhs, copy_options __rhs) {
+ return static_cast<copy_options>(static_cast<unsigned short>(__lhs) ^
+ static_cast<unsigned short>(__rhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline constexpr copy_options operator~(copy_options _LHS) {
- return static_cast<copy_options>(~static_cast<unsigned short>(_LHS));
+inline constexpr copy_options operator~(copy_options __lhs) {
+ return static_cast<copy_options>(~static_cast<unsigned short>(__lhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) {
- return _LHS = _LHS & _RHS;
+inline copy_options& operator&=(copy_options& __lhs, copy_options __rhs) {
+ return __lhs = __lhs & __rhs;
}
_LIBCPP_INLINE_VISIBILITY
-inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) {
- return _LHS = _LHS | _RHS;
+inline copy_options& operator|=(copy_options& __lhs, copy_options __rhs) {
+ return __lhs = __lhs | __rhs;
}
_LIBCPP_INLINE_VISIBILITY
-inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) {
- return _LHS = _LHS ^ _RHS;
+inline copy_options& operator^=(copy_options& __lhs, copy_options __rhs) {
+ return __lhs = __lhs ^ __rhs;
}
_LIBCPP_AVAILABILITY_FILESYSTEM_POP
diff --git a/libcxx/include/__filesystem/directory_options.h b/libcxx/include/__filesystem/directory_options.h
index d3f8cc1deb21..c5c031a567cf 100644
--- a/libcxx/include/__filesystem/directory_options.h
+++ b/libcxx/include/__filesystem/directory_options.h
@@ -30,47 +30,47 @@ enum class _LIBCPP_ENUM_VIS directory_options : unsigned char {
};
_LIBCPP_INLINE_VISIBILITY
-inline constexpr directory_options operator&(directory_options _LHS,
- directory_options _RHS) {
- return static_cast<directory_options>(static_cast<unsigned char>(_LHS) &
- static_cast<unsigned char>(_RHS));
+inline constexpr directory_options operator&(directory_options __lhs,
+ directory_options __rhs) {
+ return static_cast<directory_options>(static_cast<unsigned char>(__lhs) &
+ static_cast<unsigned char>(__rhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline constexpr directory_options operator|(directory_options _LHS,
- directory_options _RHS) {
- return static_cast<directory_options>(static_cast<unsigned char>(_LHS) |
- static_cast<unsigned char>(_RHS));
+inline constexpr directory_options operator|(directory_options __lhs,
+ directory_options __rhs) {
+ return static_cast<directory_options>(static_cast<unsigned char>(__lhs) |
+ static_cast<unsigned char>(__rhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline constexpr directory_options operator^(directory_options _LHS,
- directory_options _RHS) {
- return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^
- static_cast<unsigned char>(_RHS));
+inline constexpr directory_options operator^(directory_options __lhs,
+ directory_options __rhs) {
+ return static_cast<directory_options>(static_cast<unsigned char>(__lhs) ^
+ static_cast<unsigned char>(__rhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline constexpr directory_options operator~(directory_options _LHS) {
- return static_cast<directory_options>(~static_cast<unsigned char>(_LHS));
+inline constexpr directory_options operator~(directory_options __lhs) {
+ return static_cast<directory_options>(~static_cast<unsigned char>(__lhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline directory_options& operator&=(directory_options& _LHS,
- directory_options _RHS) {
- return _LHS = _LHS & _RHS;
+inline directory_options& operator&=(directory_options& __lhs,
+ directory_options __rhs) {
+ return __lhs = __lhs & __rhs;
}
_LIBCPP_INLINE_VISIBILITY
-inline directory_options& operator|=(directory_options& _LHS,
- directory_options _RHS) {
- return _LHS = _LHS | _RHS;
+inline directory_options& operator|=(directory_options& __lhs,
+ directory_options __rhs) {
+ return __lhs = __lhs | __rhs;
}
_LIBCPP_INLINE_VISIBILITY
-inline directory_options& operator^=(directory_options& _LHS,
- directory_options _RHS) {
- return _LHS = _LHS ^ _RHS;
+inline directory_options& operator^=(directory_options& __lhs,
+ directory_options __rhs) {
+ return __lhs = __lhs ^ __rhs;
}
_LIBCPP_AVAILABILITY_FILESYSTEM_POP
diff --git a/libcxx/include/__filesystem/operations.h b/libcxx/include/__filesystem/operations.h
index 85c71f017f34..f48d301d090c 100644
--- a/libcxx/include/__filesystem/operations.h
+++ b/libcxx/include/__filesystem/operations.h
@@ -39,10 +39,10 @@ _LIBCPP_FUNC_VIS path __canonical(const path&, error_code* __ec = nullptr);
_LIBCPP_FUNC_VIS bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr);
_LIBCPP_FUNC_VIS void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr);
_LIBCPP_FUNC_VIS void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS bool __create_directories(const path& p, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS bool __create_directories(const path&, error_code* = nullptr);
_LIBCPP_FUNC_VIS void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS bool __create_directory(const path& p, error_code* ec = nullptr);
-_LIBCPP_FUNC_VIS bool __create_directory(const path& p, const path& attributes, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS bool __create_directory(const path&, error_code* = nullptr);
+_LIBCPP_FUNC_VIS bool __create_directory(const path&, const path& __attributes, error_code* = nullptr);
_LIBCPP_FUNC_VIS void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr);
_LIBCPP_FUNC_VIS void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr);
_LIBCPP_FUNC_VIS path __current_path(error_code* __ec = nullptr);
@@ -52,14 +52,14 @@ _LIBCPP_FUNC_VIS file_status __status(const path&, error_code* __ec = nullptr);
_LIBCPP_FUNC_VIS uintmax_t __file_size(const path&, error_code* __ec = nullptr);
_LIBCPP_FUNC_VIS uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr);
_LIBCPP_FUNC_VIS file_status __symlink_status(const path&, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS file_time_type __last_write_time(const path& p, error_code* ec = nullptr);
-_LIBCPP_FUNC_VIS void __last_write_time(const path& p, file_time_type new_time, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS file_time_type __last_write_time(const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS void __last_write_time(const path&, file_time_type __new_time, error_code* __ec = nullptr);
_LIBCPP_FUNC_VIS path __weakly_canonical(path const& __p, error_code* __ec = nullptr);
-_LIBCPP_FUNC_VIS path __read_symlink(const path& p, error_code* ec = nullptr);
-_LIBCPP_FUNC_VIS uintmax_t __remove_all(const path& p, error_code* ec = nullptr);
-_LIBCPP_FUNC_VIS bool __remove(const path& p, error_code* ec = nullptr);
-_LIBCPP_FUNC_VIS void __rename(const path& from, const path& to, error_code* ec = nullptr);
-_LIBCPP_FUNC_VIS void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS path __read_symlink(const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS uintmax_t __remove_all(const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS bool __remove(const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS void __rename(const path& __from, const path& __to, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS void __resize_file(const path&, uintmax_t __size, error_code* = nullptr);
_LIBCPP_FUNC_VIS path __temp_directory_path(error_code* __ec = nullptr);
inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p) { return __absolute(__p); }
@@ -118,7 +118,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p, error_code&
inline _LIBCPP_HIDE_FROM_ABI bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; }
inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p) { return is_directory(__status(__p)); }
inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p, error_code& __ec) noexcept { return is_directory(__status(__p, &__ec)); }
-_LIBCPP_FUNC_VIS bool __fs_is_empty(const path& p, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS bool __fs_is_empty(const path& __p, error_code* __ec = nullptr);
inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p) { return __fs_is_empty(__p); }
inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p, error_code& __ec) { return __fs_is_empty(__p, &__ec); }
inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; }
diff --git a/libcxx/include/__filesystem/perm_options.h b/libcxx/include/__filesystem/perm_options.h
index f7580a2473d0..4aba302edfbe 100644
--- a/libcxx/include/__filesystem/perm_options.h
+++ b/libcxx/include/__filesystem/perm_options.h
@@ -31,41 +31,41 @@ enum class _LIBCPP_ENUM_VIS perm_options : unsigned char {
};
_LIBCPP_INLINE_VISIBILITY
-inline constexpr perm_options operator&(perm_options _LHS, perm_options _RHS) {
- return static_cast<perm_options>(static_cast<unsigned>(_LHS) &
- static_cast<unsigned>(_RHS));
+inline constexpr perm_options operator&(perm_options __lhs, perm_options __rhs) {
+ return static_cast<perm_options>(static_cast<unsigned>(__lhs) &
+ static_cast<unsigned>(__rhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline constexpr perm_options operator|(perm_options _LHS, perm_options _RHS) {
- return static_cast<perm_options>(static_cast<unsigned>(_LHS) |
- static_cast<unsigned>(_RHS));
+inline constexpr perm_options operator|(perm_options __lhs, perm_options __rhs) {
+ return static_cast<perm_options>(static_cast<unsigned>(__lhs) |
+ static_cast<unsigned>(__rhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline constexpr perm_options operator^(perm_options _LHS, perm_options _RHS) {
- return static_cast<perm_options>(static_cast<unsigned>(_LHS) ^
- static_cast<unsigned>(_RHS));
+inline constexpr perm_options operator^(perm_options __lhs, perm_options __rhs) {
+ return static_cast<perm_options>(static_cast<unsigned>(__lhs) ^
+ static_cast<unsigned>(__rhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline constexpr perm_options operator~(perm_options _LHS) {
- return static_cast<perm_options>(~static_cast<unsigned>(_LHS));
+inline constexpr perm_options operator~(perm_options __lhs) {
+ return static_cast<perm_options>(~static_cast<unsigned>(__lhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline perm_options& operator&=(perm_options& _LHS, perm_options _RHS) {
- return _LHS = _LHS & _RHS;
+inline perm_options& operator&=(perm_options& __lhs, perm_options __rhs) {
+ return __lhs = __lhs & __rhs;
}
_LIBCPP_INLINE_VISIBILITY
-inline perm_options& operator|=(perm_options& _LHS, perm_options _RHS) {
- return _LHS = _LHS | _RHS;
+inline perm_options& operator|=(perm_options& __lhs, perm_options __rhs) {
+ return __lhs = __lhs | __rhs;
}
_LIBCPP_INLINE_VISIBILITY
-inline perm_options& operator^=(perm_options& _LHS, perm_options _RHS) {
- return _LHS = _LHS ^ _RHS;
+inline perm_options& operator^=(perm_options& __lhs, perm_options __rhs) {
+ return __lhs = __lhs ^ __rhs;
}
_LIBCPP_AVAILABILITY_FILESYSTEM_POP
diff --git a/libcxx/include/__filesystem/perms.h b/libcxx/include/__filesystem/perms.h
index 0e5c7ed8d2e9..df4590057ee1 100644
--- a/libcxx/include/__filesystem/perms.h
+++ b/libcxx/include/__filesystem/perms.h
@@ -55,36 +55,36 @@ enum class _LIBCPP_ENUM_VIS perms : unsigned {
};
_LIBCPP_INLINE_VISIBILITY
-inline constexpr perms operator&(perms _LHS, perms _RHS) {
- return static_cast<perms>(static_cast<unsigned>(_LHS) &
- static_cast<unsigned>(_RHS));
+inline constexpr perms operator&(perms __lhs, perms __rhs) {
+ return static_cast<perms>(static_cast<unsigned>(__lhs) &
+ static_cast<unsigned>(__rhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline constexpr perms operator|(perms _LHS, perms _RHS) {
- return static_cast<perms>(static_cast<unsigned>(_LHS) |
- static_cast<unsigned>(_RHS));
+inline constexpr perms operator|(perms __lhs, perms __rhs) {
+ return static_cast<perms>(static_cast<unsigned>(__lhs) |
+ static_cast<unsigned>(__rhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline constexpr perms operator^(perms _LHS, perms _RHS) {
- return static_cast<perms>(static_cast<unsigned>(_LHS) ^
- static_cast<unsigned>(_RHS));
+inline constexpr perms operator^(perms __lhs, perms __rhs) {
+ return static_cast<perms>(static_cast<unsigned>(__lhs) ^
+ static_cast<unsigned>(__rhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline constexpr perms operator~(perms _LHS) {
- return static_cast<perms>(~static_cast<unsigned>(_LHS));
+inline constexpr perms operator~(perms __lhs) {
+ return static_cast<perms>(~static_cast<unsigned>(__lhs));
}
_LIBCPP_INLINE_VISIBILITY
-inline perms& operator&=(perms& _LHS, perms _RHS) { return _LHS = _LHS & _RHS; }
+inline perms& operator&=(perms& __lhs, perms __rhs) { return __lhs = __lhs & __rhs; }
_LIBCPP_INLINE_VISIBILITY
-inline perms& operator|=(perms& _LHS, perms _RHS) { return _LHS = _LHS | _RHS; }
+inline perms& operator|=(perms& __lhs, perms __rhs) { return __lhs = __lhs | __rhs; }
_LIBCPP_INLINE_VISIBILITY
-inline perms& operator^=(perms& _LHS, perms _RHS) { return _LHS = _LHS ^ _RHS; }
+inline perms& operator^=(perms& __lhs, perms __rhs) { return __lhs = __lhs ^ __rhs; }
_LIBCPP_AVAILABILITY_FILESYSTEM_POP
diff --git a/libcxx/include/__format/format_arg.h b/libcxx/include/__format/format_arg.h
index 3f2afc898d2c..4f93024b7c69 100644
--- a/libcxx/include/__format/format_arg.h
+++ b/libcxx/include/__format/format_arg.h
@@ -147,15 +147,20 @@ public:
/// Contains the implementation for basic_format_arg::handle.
struct __handle {
template <class _Tp>
- _LIBCPP_HIDE_FROM_ABI explicit __handle(const _Tp& __v) noexcept
+ _LIBCPP_HIDE_FROM_ABI explicit __handle(_Tp&& __v) noexcept
: __ptr_(_VSTD::addressof(__v)),
__format_([](basic_format_parse_context<_CharT>& __parse_ctx, _Context& __ctx, const void* __ptr) {
- using _Formatter = typename _Context::template formatter_type<_Tp>;
- using _Qp = conditional_t<requires { _Formatter().format(declval<const _Tp&>(), declval<_Context&>()); },
- const _Tp, _Tp>;
+ using _Dp = remove_cvref_t<_Tp>;
+ using _Formatter = typename _Context::template formatter_type<_Dp>;
+ constexpr bool __const_formattable =
+ requires { _Formatter().format(declval<const _Dp&>(), declval<_Context&>()); };
+ using _Qp = conditional_t<__const_formattable, const _Dp, _Dp>;
+
+ static_assert(__const_formattable || !is_const_v<remove_reference_t<_Tp>>, "Mandated by [format.arg]/18");
+
_Formatter __f;
__parse_ctx.advance_to(__f.parse(__parse_ctx));
- __ctx.advance_to(__f.format(*const_cast<_Qp*>(static_cast<const _Tp*>(__ptr)), __ctx));
+ __ctx.advance_to(__f.format(*const_cast<_Qp*>(static_cast<const _Dp*>(__ptr)), __ctx));
}) {}
const void* __ptr_;
@@ -205,7 +210,9 @@ public:
_LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(basic_string_view<_CharT> __value) noexcept
: __string_view_(__value) {}
_LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const void* __value) noexcept : __ptr_(__value) {}
- _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle __value) noexcept : __handle_(__value) {}
+ _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle __value) noexcept
+ // TODO FMT Investigate why it doesn't work without the forward.
+ : __handle_(std::forward<__handle>(__value)) {}
};
template <class _Context>
@@ -251,11 +258,11 @@ public:
__handle_.__format_(__parse_ctx, __ctx, __handle_.__ptr_);
}
- _LIBCPP_HIDE_FROM_ABI explicit handle(typename __basic_format_arg_value<_Context>::__handle __handle) noexcept
+ _LIBCPP_HIDE_FROM_ABI explicit handle(typename __basic_format_arg_value<_Context>::__handle& __handle) noexcept
: __handle_(__handle) {}
private:
- typename __basic_format_arg_value<_Context>::__handle __handle_;
+ typename __basic_format_arg_value<_Context>::__handle& __handle_;
};
#endif //_LIBCPP_STD_VER > 17
diff --git a/libcxx/include/__format/format_arg_store.h b/libcxx/include/__format/format_arg_store.h
index 6602dfeb956b..26a5e71b93af 100644
--- a/libcxx/include/__format/format_arg_store.h
+++ b/libcxx/include/__format/format_arg_store.h
@@ -197,7 +197,7 @@ _LIBCPP_HIDE_FROM_ABI void __create_packed_storage(uint64_t& __types, __basic_fo
int __shift = 0;
(
[&] {
- basic_format_arg<_Context> __arg = __create_format_arg<_Context>(_VSTD::forward<_Args>(__args));
+ basic_format_arg<_Context> __arg = __create_format_arg<_Context>(__args);
if (__shift != 0)
__types |= static_cast<uint64_t>(__arg.__type_) << __shift;
else
@@ -211,7 +211,7 @@ _LIBCPP_HIDE_FROM_ABI void __create_packed_storage(uint64_t& __types, __basic_fo
template <class _Context, class... _Args>
_LIBCPP_HIDE_FROM_ABI void __store_basic_format_arg(basic_format_arg<_Context>* __data, _Args&&... __args) noexcept {
- ([&] { *__data++ = __create_format_arg<_Context>(_VSTD::forward<_Args>(__args)); }(), ...);
+ ([&] { *__data++ = __create_format_arg<_Context>(__args); }(), ...);
}
template <class _Context, size_t N>
@@ -230,12 +230,12 @@ struct __unpacked_format_arg_store {
template <class _Context, class... _Args>
struct _LIBCPP_TEMPLATE_VIS __format_arg_store {
_LIBCPP_HIDE_FROM_ABI
- __format_arg_store(_Args&&... __args) noexcept {
+ __format_arg_store(_Args&... __args) noexcept {
if constexpr (sizeof...(_Args) != 0) {
if constexpr (__format::__use_packed_format_arg_store(sizeof...(_Args)))
- __format::__create_packed_storage(__storage.__types_, __storage.__values_, _VSTD::forward<_Args>(__args)...);
+ __format::__create_packed_storage(__storage.__types_, __storage.__values_, __args...);
else
- __format::__store_basic_format_arg<_Context>(__storage.__args_, _VSTD::forward<_Args>(__args)...);
+ __format::__store_basic_format_arg<_Context>(__storage.__args_, __args...);
}
}
diff --git a/libcxx/include/__format/formatter.h b/libcxx/include/__format/formatter.h
index c39e25b354eb..4816f961c445 100644
--- a/libcxx/include/__format/formatter.h
+++ b/libcxx/include/__format/formatter.h
@@ -10,20 +10,10 @@
#ifndef _LIBCPP___FORMAT_FORMATTER_H
#define _LIBCPP___FORMAT_FORMATTER_H
-#include <__algorithm/copy.h>
-#include <__algorithm/fill_n.h>
-#include <__algorithm/transform.h>
-#include <__assert>
#include <__availability>
#include <__concepts/same_as.h>
#include <__config>
-#include <__format/format_error.h>
#include <__format/format_fwd.h>
-#include <__format/format_string.h>
-#include <__format/parser_std_format_spec.h>
-#include <__utility/move.h>
-#include <__utility/unreachable.h>
-#include <string_view>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -49,229 +39,12 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter {
formatter& operator=(const formatter&) = delete;
};
-namespace __format_spec {
-
-_LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative,
- _Flags::_Sign __sign) {
- if (__negative)
- *__buf++ = '-';
- else
- switch (__sign) {
- case _Flags::_Sign::__default:
- case _Flags::_Sign::__minus:
- // No sign added.
- break;
- case _Flags::_Sign::__plus:
- *__buf++ = '+';
- break;
- case _Flags::_Sign::__space:
- *__buf++ = ' ';
- break;
- }
-
- return __buf;
-}
-
-_LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char c) {
- switch (c) {
- case 'a':
- return 'A';
- case 'b':
- return 'B';
- case 'c':
- return 'C';
- case 'd':
- return 'D';
- case 'e':
- return 'E';
- case 'f':
- return 'F';
- }
- return c;
-}
-
-} // namespace __format_spec
-
namespace __formatter {
/** The character types that formatters are specialized for. */
template <class _CharT>
concept __char_type = same_as<_CharT, char> || same_as<_CharT, wchar_t>;
-struct _LIBCPP_TEMPLATE_VIS __padding_size_result {
- size_t __before;
- size_t __after;
-};
-
-_LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result
-__padding_size(size_t __size, size_t __width,
- __format_spec::_Flags::_Alignment __align) {
- _LIBCPP_ASSERT(__width > __size,
- "Don't call this function when no padding is required");
- _LIBCPP_ASSERT(
- __align != __format_spec::_Flags::_Alignment::__default,
- "Caller should adjust the default to the value required by the type");
-
- size_t __fill = __width - __size;
- switch (__align) {
- case __format_spec::_Flags::_Alignment::__default:
- __libcpp_unreachable();
-
- case __format_spec::_Flags::_Alignment::__left:
- return {0, __fill};
-
- case __format_spec::_Flags::_Alignment::__center: {
- // The extra padding is divided per [format.string.std]/3
- // __before = floor(__fill, 2);
- // __after = ceil(__fill, 2);
- size_t __before = __fill / 2;
- size_t __after = __fill - __before;
- return {__before, __after};
- }
- case __format_spec::_Flags::_Alignment::__right:
- return {__fill, 0};
- }
- __libcpp_unreachable();
-}
-
-/**
- * Writes the input to the output with the required padding.
- *
- * Since the output column width is specified the function can be used for
- * ASCII and Unicode input.
- *
- * @pre [@a __first, @a __last) is a valid range.
- * @pre @a __size <= @a __width. Using this function when this pre-condition
- * doesn't hold incurs an unwanted overhead.
- *
- * @param __out_it The output iterator to write to.
- * @param __first Pointer to the first element to write.
- * @param __last Pointer beyond the last element to write.
- * @param __size The (estimated) output column width. When the elements
- * to be written are ASCII the following condition holds
- * @a __size == @a __last - @a __first.
- * @param __width The number of output columns to write.
- * @param __fill The character used for the alignment of the output.
- * TODO FMT Will probably change to support Unicode grapheme
- * cluster.
- * @param __alignment The requested alignment.
- *
- * @returns An iterator pointing beyond the last element written.
- *
- * @note The type of the elements in range [@a __first, @a __last) can differ
- * from the type of @a __fill. Integer output uses @c std::to_chars for its
- * conversion, which means the [@a __first, @a __last) always contains elements
- * of the type @c char.
- */
-template <class _CharT, class _Fill>
-_LIBCPP_HIDE_FROM_ABI auto
-__write(output_iterator<const _CharT&> auto __out_it, const _CharT* __first,
- const _CharT* __last, size_t __size, size_t __width, _Fill __fill,
- __format_spec::_Flags::_Alignment __alignment) -> decltype(__out_it) {
-
- _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
- _LIBCPP_ASSERT(__size < __width, "Precondition failure");
-
- __padding_size_result __padding =
- __padding_size(__size, __width, __alignment);
- __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill);
- __out_it = _VSTD::copy(__first, __last, _VSTD::move(__out_it));
- return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill);
-}
-
-/**
- * @overload
- *
- * Writes additional zero's for the precision before the exponent.
- * This is used when the precision requested in the format string is larger
- * than the maximum precision of the floating-point type. These precision
- * digits are always 0.
- *
- * @param __exponent The location of the exponent character.
- * @param __num_trailing_zeros The number of 0's to write before the exponent
- * character.
- */
-template <class _CharT, class _Fill>
-_LIBCPP_HIDE_FROM_ABI auto __write(output_iterator<const _CharT&> auto __out_it, const _CharT* __first,
- const _CharT* __last, size_t __size, size_t __width, _Fill __fill,
- __format_spec::_Flags::_Alignment __alignment, const _CharT* __exponent,
- size_t __num_trailing_zeros) -> decltype(__out_it) {
- _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
- _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used");
-
- __padding_size_result __padding = __padding_size(__size + __num_trailing_zeros, __width, __alignment);
- __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill);
- __out_it = _VSTD::copy(__first, __exponent, _VSTD::move(__out_it));
- __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0'));
- __out_it = _VSTD::copy(__exponent, __last, _VSTD::move(__out_it));
- return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill);
-}
-
-/**
- * @overload
- *
- * Uses a transformation operation before writing an element.
- *
- * TODO FMT Fill will probably change to support Unicode grapheme cluster.
- */
-template <class _CharT, class _UnaryOperation, class _Fill>
-_LIBCPP_HIDE_FROM_ABI auto
-__write(output_iterator<const _CharT&> auto __out_it, const _CharT* __first,
- const _CharT* __last, size_t __size, _UnaryOperation __op,
- size_t __width, _Fill __fill,
- __format_spec::_Flags::_Alignment __alignment) -> decltype(__out_it) {
-
- _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
- _LIBCPP_ASSERT(__size < __width, "Precondition failure");
-
- __padding_size_result __padding =
- __padding_size(__size, __width, __alignment);
- __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill);
- __out_it = _VSTD::transform(__first, __last, _VSTD::move(__out_it), __op);
- return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill);
-}
-
-/**
- * Writes Unicode input to the output with the required padding.
- *
- * This function does almost the same as the @ref __write function, but handles
- * the width estimation of the Unicode input.
- *
- * @param __str The range [@a __first, @a __last).
- * @param __precision The width to truncate the input string to, use @c -1 for
- * no limit.
- */
-template <class _CharT, class _Fill>
-_LIBCPP_HIDE_FROM_ABI auto
-__write_unicode(output_iterator<const _CharT&> auto __out_it,
- basic_string_view<_CharT> __str, ptrdiff_t __width,
- ptrdiff_t __precision, _Fill __fill,
- __format_spec::_Flags::_Alignment __alignment)
- -> decltype(__out_it) {
-
- // This value changes when there Unicode column width limits the output
- // size.
- auto __last = __str.end();
- if (__width != 0 || __precision != -1) {
- __format_spec::__string_alignment<_CharT> __format_traits =
- __format_spec::__get_string_alignment(__str.begin(), __str.end(),
- __width, __precision);
-
- if (__format_traits.__align)
- return __write(_VSTD::move(__out_it), __str.begin(),
- __format_traits.__last, __format_traits.__size, __width,
- __fill, __alignment);
-
- // No alignment required update the output based on the precision.
- // This might be the same as __str.end().
- __last = __format_traits.__last;
- }
-
- // Copy the input to the output. The output size might be limited by the
- // precision.
- return _VSTD::copy(__str.begin(), __last, _VSTD::move(__out_it));
-}
-
} // namespace __formatter
#endif //_LIBCPP_STD_VER > 17
diff --git a/libcxx/include/__format/formatter_bool.h b/libcxx/include/__format/formatter_bool.h
index 4c9d3fc77473..cdb0631f87d4 100644
--- a/libcxx/include/__format/formatter_bool.h
+++ b/libcxx/include/__format/formatter_bool.h
@@ -47,6 +47,7 @@ public:
_LIBCPP_HIDE_FROM_ABI auto format(bool __value, auto& __ctx) const -> decltype(__ctx.out()) {
switch (__parser_.__type_) {
+ case __format_spec::__type::__default:
case __format_spec::__type::__string:
return __formatter::__format_bool(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx));
diff --git a/libcxx/include/__format/formatter_char.h b/libcxx/include/__format/formatter_char.h
index cd54abba348a..a3ca36ec0a62 100644
--- a/libcxx/include/__format/formatter_char.h
+++ b/libcxx/include/__format/formatter_char.h
@@ -41,7 +41,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI auto format(_CharT __value, auto& __ctx) const -> decltype(__ctx.out()) {
- if (__parser_.__type_ == __format_spec::__type::__char)
+ if (__parser_.__type_ == __format_spec::__type::__default || __parser_.__type_ == __format_spec::__type::__char)
return __formatter::__format_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
if constexpr (sizeof(_CharT) <= sizeof(int))
diff --git a/libcxx/include/__format/formatter_floating_point.h b/libcxx/include/__format/formatter_floating_point.h
index c9f5689abd8b..90a76193196e 100644
--- a/libcxx/include/__format/formatter_floating_point.h
+++ b/libcxx/include/__format/formatter_floating_point.h
@@ -17,21 +17,19 @@
#include <__algorithm/min.h>
#include <__algorithm/rotate.h>
#include <__algorithm/transform.h>
-#include <__assert>
#include <__concepts/arithmetic.h>
#include <__concepts/same_as.h>
#include <__config>
-#include <__format/format_error.h>
#include <__format/format_fwd.h>
-#include <__format/format_string.h>
+#include <__format/format_parse_context.h>
#include <__format/formatter.h>
#include <__format/formatter_integral.h>
+#include <__format/formatter_output.h>
#include <__format/parser_std_format_spec.h>
#include <__memory/allocator.h>
#include <__utility/move.h>
#include <__utility/unreachable.h>
#include <charconv>
-#include <cmath>
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
# include <locale>
@@ -48,7 +46,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-namespace __format_spec {
+namespace __formatter {
template <floating_point _Tp>
_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value) {
@@ -164,7 +162,7 @@ public:
__precision_ = _Traits::__max_fractional;
}
- __size_ = __format_spec::__float_buffer_size<_Fp>(__precision_);
+ __size_ = __formatter::__float_buffer_size<_Fp>(__precision_);
if (__size_ > _Traits::__stack_buffer_size)
// The allocated buffer's contents don't need initialization.
__begin_ = allocator<char>{}.allocate(__size_);
@@ -233,9 +231,9 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffe
char* __integral) {
__float_result __result;
__result.__integral = __integral;
- __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value);
+ __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value);
- __result.__exponent = __format_spec::__find_exponent(__result.__integral, __result.__last);
+ __result.__exponent = __formatter::__find_exponent(__result.__integral, __result.__last);
// Constrains:
// - There's at least one decimal digit before the radix point.
@@ -264,9 +262,9 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(cons
__float_result __result;
__result.__integral = __integral;
if (__precision == -1)
- __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex);
+ __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex);
else
- __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex, __precision);
+ __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex, __precision);
// H = one or more hex-digits
// S = sign
@@ -315,7 +313,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_upper_case(cons
_Tp __value, int __precision,
char* __integral) {
__float_result __result =
- __format_spec::__format_buffer_hexadecimal_lower_case(__buffer, __value, __precision, __integral);
+ __formatter::__format_buffer_hexadecimal_lower_case(__buffer, __value, __precision, __integral);
_VSTD::transform(__result.__integral, __result.__exponent, __result.__integral, __hex_to_upper);
*__result.__exponent = 'P';
return __result;
@@ -328,13 +326,13 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const
__float_result __result;
__result.__integral = __integral;
__result.__last =
- __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::scientific, __precision);
+ __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::scientific, __precision);
char* __first = __integral + 1;
_LIBCPP_ASSERT(__first != __result.__last, "No exponent present");
if (*__first == '.') {
__result.__radix_point = __first;
- __result.__exponent = __format_spec::__find_exponent(__first + 1, __result.__last);
+ __result.__exponent = __formatter::__find_exponent(__first + 1, __result.__last);
} else {
__result.__radix_point = __result.__last;
__result.__exponent = __first;
@@ -354,7 +352,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_upper_case(const
_Tp __value, int __precision,
char* __integral) {
__float_result __result =
- __format_spec::__format_buffer_scientific_lower_case(__buffer, __value, __precision, __integral);
+ __formatter::__format_buffer_scientific_lower_case(__buffer, __value, __precision, __integral);
*__result.__exponent = 'E';
return __result;
}
@@ -364,7 +362,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer<
int __precision, char* __integral) {
__float_result __result;
__result.__integral = __integral;
- __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::fixed, __precision);
+ __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::fixed, __precision);
// When there's no precision there's no radix point.
// Else the radix point is placed at __precision + 1 from the end.
@@ -390,14 +388,14 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_
__float_result __result;
__result.__integral = __integral;
- __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::general, __precision);
+ __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::general, __precision);
char* __first = __integral + 1;
if (__first == __result.__last) {
__result.__radix_point = __result.__last;
__result.__exponent = __result.__last;
} else {
- __result.__exponent = __format_spec::__find_exponent(__first, __result.__last);
+ __result.__exponent = __formatter::__find_exponent(__first, __result.__last);
if (__result.__exponent != __result.__last)
// In scientific mode if there's a radix point it will always be after
// the first digit. (This is the position __first points at).
@@ -423,19 +421,79 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_
template <class _Fp, class _Tp>
_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_upper_case(__float_buffer<_Fp>& __buffer, _Tp __value,
int __precision, char* __integral) {
- __float_result __result =
- __format_spec::__format_buffer_general_lower_case(__buffer, __value, __precision, __integral);
+ __float_result __result = __formatter::__format_buffer_general_lower_case(__buffer, __value, __precision, __integral);
if (__result.__exponent != __result.__last)
*__result.__exponent = 'E';
return __result;
}
-# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+/// Fills the buffer with the data based on the requested formatting.
+///
+/// This function, when needed, turns the characters to upper case and
+/// determines the "interesting" locations which are returned to the caller.
+///
+/// This means the caller never has to convert the contents of the buffer to
+/// upper case or search for radix points and the location of the exponent.
+/// This gives a bit of overhead. The original code didn't do that, but due
+/// to the number of possible additional work needed to turn this number to
+/// the proper output the code was littered with tests for upper cases and
+/// searches for radix points and exponents.
+/// - When a precision larger than the type's precision is selected
+/// additional zero characters need to be written before the exponent.
+/// - alternate form needs to add a radix point when not present.
+/// - localization needs to do grouping in the integral part.
+template <class _Fp, class _Tp>
+// TODO FMT _Fp should just be _Tp when to_chars has proper long double support.
+_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer(
+ __float_buffer<_Fp>& __buffer,
+ _Tp __value,
+ bool __negative,
+ bool __has_precision,
+ __format_spec::__sign __sign,
+ __format_spec::__type __type) {
+ char* __first = __formatter::__insert_sign(__buffer.begin(), __negative, __sign);
+ switch (__type) {
+ case __format_spec::__type::__default:
+ return __formatter::__format_buffer_default(__buffer, __value, __first);
+
+ case __format_spec::__type::__hexfloat_lower_case:
+ return __formatter::__format_buffer_hexadecimal_lower_case(
+ __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first);
+
+ case __format_spec::__type::__hexfloat_upper_case:
+ return __formatter::__format_buffer_hexadecimal_upper_case(
+ __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first);
+
+ case __format_spec::__type::__scientific_lower_case:
+ return __formatter::__format_buffer_scientific_lower_case(__buffer, __value, __buffer.__precision(), __first);
+
+ case __format_spec::__type::__scientific_upper_case:
+ return __formatter::__format_buffer_scientific_upper_case(__buffer, __value, __buffer.__precision(), __first);
+
+ case __format_spec::__type::__fixed_lower_case:
+ case __format_spec::__type::__fixed_upper_case:
+ return __formatter::__format_buffer_fixed(__buffer, __value, __buffer.__precision(), __first);
+
+ case __format_spec::__type::__general_lower_case:
+ return __formatter::__format_buffer_general_lower_case(__buffer, __value, __buffer.__precision(), __first);
+
+ case __format_spec::__type::__general_upper_case:
+ return __formatter::__format_buffer_general_upper_case(__buffer, __value, __buffer.__precision(), __first);
+
+ default:
+ _LIBCPP_ASSERT(false, "The parser should have validated the type");
+ __libcpp_unreachable();
+ }
+}
+
+# ifndef _LIBCPP_HAS_NO_LOCALIZATION
template <class _OutIt, class _Fp, class _CharT>
-_LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(_OutIt __out_it, const __float_buffer<_Fp>& __buffer,
- const __float_result& __result, _VSTD::locale __loc,
- size_t __width, _Flags::_Alignment __alignment,
- _CharT __fill) {
+_LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(
+ _OutIt __out_it,
+ const __float_buffer<_Fp>& __buffer,
+ const __float_result& __result,
+ _VSTD::locale __loc,
+ __format_spec::__parsed_specifications<_CharT> __specs) {
const auto& __np = use_facet<numpunct<_CharT>>(__loc);
string __grouping = __np.grouping();
char* __first = __result.__integral;
@@ -450,26 +508,27 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(_OutIt __out_it, cons
__grouping = __formatter::__determine_grouping(__digits, __grouping);
}
- size_t __size = __result.__last - __buffer.begin() + // Formatted string
- __buffer.__num_trailing_zeros() + // Not yet rendered zeros
- __grouping.size() - // Grouping contains one
- !__grouping.empty(); // additional character
+ ptrdiff_t __size =
+ __result.__last - __buffer.begin() + // Formatted string
+ __buffer.__num_trailing_zeros() + // Not yet rendered zeros
+ __grouping.size() - // Grouping contains one
+ !__grouping.empty(); // additional character
- __formatter::__padding_size_result __padding = {0, 0};
- bool __zero_padding = __alignment == _Flags::_Alignment::__default;
- if (__size < __width) {
+ __formatter::__padding_size_result __padding = {0, 0};
+ bool __zero_padding = __specs.__alignment_ == __format_spec::__alignment::__zero_padding;
+ if (__size < __specs.__width_) {
if (__zero_padding) {
- __alignment = _Flags::_Alignment::__right;
- __fill = _CharT('0');
+ __specs.__alignment_ = __format_spec::__alignment::__right;
+ __specs.__fill_ = _CharT('0');
}
- __padding = __formatter::__padding_size(__size, __width, __alignment);
+ __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_);
}
// sign and (zero padding or alignment)
if (__zero_padding && __first != __buffer.begin())
*__out_it++ = *__buffer.begin();
- __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill);
+ __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
if (!__zero_padding && __first != __buffer.begin())
*__out_it++ = *__buffer.begin();
@@ -510,198 +569,148 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(_OutIt __out_it, cons
__out_it = _VSTD::copy(__result.__exponent, __result.__last, _VSTD::move(__out_it));
// alignment
- return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill);
+ return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
+}
+# endif // _LIBCPP_HAS_NO_LOCALIZATION
+
+template <class _OutIt, class _CharT>
+_LIBCPP_HIDE_FROM_ABI _OutIt __format_floating_point_non_finite(
+ _OutIt __out_it, __format_spec::__parsed_specifications<_CharT> __specs, bool __negative, bool __isnan) {
+ char __buffer[4];
+ char* __last = __formatter::__insert_sign(__buffer, __negative, __specs.__std_.__sign_);
+
+ // to_chars can return inf, infinity, nan, and nan(n-char-sequence).
+ // The format library requires inf and nan.
+ // All in one expression to avoid dangling references.
+ bool __upper_case =
+ __specs.__std_.__type_ == __format_spec::__type::__hexfloat_upper_case ||
+ __specs.__std_.__type_ == __format_spec::__type::__scientific_upper_case ||
+ __specs.__std_.__type_ == __format_spec::__type::__fixed_upper_case ||
+ __specs.__std_.__type_ == __format_spec::__type::__general_upper_case;
+ __last = _VSTD::copy_n(&("infnanINFNAN"[6 * __upper_case + 3 * __isnan]), 3, __last);
+
+ // [format.string.std]/13
+ // A zero (0) character preceding the width field pads the field with
+ // leading zeros (following any indication of sign or base) to the field
+ // width, except when applied to an infinity or NaN.
+ if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding)
+ __specs.__alignment_ = __format_spec::__alignment::__right;
+
+ return __formatter::__write(__buffer, __last, _VSTD::move(__out_it), __specs);
}
-# endif // _LIBCPP_HAS_NO_LOCALIZATION
-
-template <__formatter::__char_type _CharT>
-class _LIBCPP_TEMPLATE_VIS __formatter_floating_point : public __parser_floating_point<_CharT> {
-public:
- template <floating_point _Tp>
- _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) -> decltype(__ctx.out()) {
- if (this->__width_needs_substitution())
- this->__substitute_width_arg_id(__ctx.arg(this->__width));
-
- bool __negative = _VSTD::signbit(__value);
-
- if (!_VSTD::isfinite(__value)) [[unlikely]]
- return __format_non_finite(__ctx.out(), __negative, _VSTD::isnan(__value));
-
- bool __has_precision = this->__has_precision_field();
- if (this->__precision_needs_substitution())
- this->__substitute_precision_arg_id(__ctx.arg(this->__precision));
-
- // Depending on the std-format-spec string the sign and the value
- // might not be outputted together:
- // - zero-padding may insert additional '0' characters.
- // Therefore the value is processed as a non negative value.
- // The function @ref __insert_sign will insert a '-' when the value was
- // negative.
-
- if (__negative)
- __value = _VSTD::copysign(__value, +1.0);
-
- // TODO FMT _Fp should just be _Tp when to_chars has proper long double support.
- using _Fp = conditional_t<same_as<_Tp, long double>, double, _Tp>;
- // Force the type of the precision to avoid -1 to become an unsigned value.
- __float_buffer<_Fp> __buffer(__has_precision ? int(this->__precision) : -1);
- __float_result __result = __format_buffer(__buffer, __value, __negative, __has_precision);
-
- if (this->__alternate_form && __result.__radix_point == __result.__last) {
- *__result.__last++ = '.';
-
- // When there is an exponent the point needs to be moved before the
- // exponent. When there's no exponent the rotate does nothing. Since
- // rotate tests whether the operation is a nop, call it unconditionally.
- _VSTD::rotate(__result.__exponent, __result.__last - 1, __result.__last);
- __result.__radix_point = __result.__exponent;
-
- // The radix point is always placed before the exponent.
- // - No exponent needs to point to the new last.
- // - An exponent needs to move one position to the right.
- // So it's safe to increment the value unconditionally.
- ++__result.__exponent;
- }
+template <floating_point _Tp, class _CharT>
+_LIBCPP_HIDE_FROM_ABI auto
+__format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs)
+ -> decltype(__ctx.out()) {
+ bool __negative = _VSTD::signbit(__value);
-# ifndef _LIBCPP_HAS_NO_LOCALIZATION
- if (this->__locale_specific_form)
- return __format_spec::__format_locale_specific_form(__ctx.out(), __buffer, __result, __ctx.locale(),
- this->__width, this->__alignment, this->__fill);
-# endif
-
- ptrdiff_t __size = __result.__last - __buffer.begin();
- int __num_trailing_zeros = __buffer.__num_trailing_zeros();
- if (__size + __num_trailing_zeros >= this->__width) {
- if (__num_trailing_zeros && __result.__exponent != __result.__last)
- // Insert trailing zeros before exponent character.
- return _VSTD::copy(__result.__exponent, __result.__last,
- _VSTD::fill_n(_VSTD::copy(__buffer.begin(), __result.__exponent, __ctx.out()),
- __num_trailing_zeros, _CharT('0')));
-
- return _VSTD::fill_n(_VSTD::copy(__buffer.begin(), __result.__last, __ctx.out()), __num_trailing_zeros,
- _CharT('0'));
- }
+ if (!_VSTD::isfinite(__value)) [[unlikely]]
+ return __formatter::__format_floating_point_non_finite(__ctx.out(), __specs, __negative, _VSTD::isnan(__value));
- auto __out_it = __ctx.out();
- char* __first = __buffer.begin();
- if (this->__alignment == _Flags::_Alignment::__default) {
- // When there is a sign output it before the padding. Note the __size
- // doesn't need any adjustment, regardless whether the sign is written
- // here or in __formatter::__write.
- if (__first != __result.__integral)
- *__out_it++ = *__first++;
- // After the sign is written, zero padding is the same a right alignment
- // with '0'.
- this->__alignment = _Flags::_Alignment::__right;
- this->__fill = _CharT('0');
- }
+ // Depending on the std-format-spec string the sign and the value
+ // might not be outputted together:
+ // - zero-padding may insert additional '0' characters.
+ // Therefore the value is processed as a non negative value.
+ // The function @ref __insert_sign will insert a '-' when the value was
+ // negative.
- if (__num_trailing_zeros)
- return __formatter::__write(_VSTD::move(__out_it), __first, __result.__last, __size, this->__width, this->__fill,
- this->__alignment, __result.__exponent, __num_trailing_zeros);
+ if (__negative)
+ __value = -__value;
- return __formatter::__write(_VSTD::move(__out_it), __first, __result.__last, __size, this->__width, this->__fill,
- this->__alignment);
+ // TODO FMT _Fp should just be _Tp when to_chars has proper long double support.
+ using _Fp = conditional_t<same_as<_Tp, long double>, double, _Tp>;
+ // Force the type of the precision to avoid -1 to become an unsigned value.
+ __float_buffer<_Fp> __buffer(__specs.__precision_);
+ __float_result __result = __formatter::__format_buffer(
+ __buffer, __value, __negative, (__specs.__has_precision()), __specs.__std_.__sign_, __specs.__std_.__type_);
+
+ if (__specs.__std_.__alternate_form_ && __result.__radix_point == __result.__last) {
+ *__result.__last++ = '.';
+
+ // When there is an exponent the point needs to be moved before the
+ // exponent. When there's no exponent the rotate does nothing. Since
+ // rotate tests whether the operation is a nop, call it unconditionally.
+ _VSTD::rotate(__result.__exponent, __result.__last - 1, __result.__last);
+ __result.__radix_point = __result.__exponent;
+
+ // The radix point is always placed before the exponent.
+ // - No exponent needs to point to the new last.
+ // - An exponent needs to move one position to the right.
+ // So it's safe to increment the value unconditionally.
+ ++__result.__exponent;
}
-private:
- template <class _OutIt>
- _LIBCPP_HIDE_FROM_ABI _OutIt __format_non_finite(_OutIt __out_it, bool __negative, bool __isnan) {
- char __buffer[4];
- char* __last = __insert_sign(__buffer, __negative, this->__sign);
-
- // to_char can return inf, infinity, nan, and nan(n-char-sequence).
- // The format library requires inf and nan.
- // All in one expression to avoid dangling references.
- __last = _VSTD::copy_n(&("infnanINFNAN"[6 * (this->__type == _Flags::_Type::__float_hexadecimal_upper_case ||
- this->__type == _Flags::_Type::__scientific_upper_case ||
- this->__type == _Flags::_Type::__fixed_upper_case ||
- this->__type == _Flags::_Type::__general_upper_case) +
- 3 * __isnan]),
- 3, __last);
-
- // [format.string.std]/13
- // A zero (0) character preceding the width field pads the field with
- // leading zeros (following any indication of sign or base) to the field
- // width, except when applied to an infinity or NaN.
- if (this->__alignment == _Flags::_Alignment::__default)
- this->__alignment = _Flags::_Alignment::__right;
-
- ptrdiff_t __size = __last - __buffer;
- if (__size >= this->__width)
- return _VSTD::copy_n(__buffer, __size, _VSTD::move(__out_it));
-
- return __formatter::__write(_VSTD::move(__out_it), __buffer, __last, __size, this->__width, this->__fill,
- this->__alignment);
+# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+ if (__specs.__std_.__locale_specific_form_)
+ return __formatter::__format_locale_specific_form(__ctx.out(), __buffer, __result, __ctx.locale(), __specs);
+# endif
+
+ ptrdiff_t __size = __result.__last - __buffer.begin();
+ int __num_trailing_zeros = __buffer.__num_trailing_zeros();
+ if (__size + __num_trailing_zeros >= __specs.__width_) {
+ if (__num_trailing_zeros && __result.__exponent != __result.__last)
+ // Insert trailing zeros before exponent character.
+ return _VSTD::copy(
+ __result.__exponent,
+ __result.__last,
+ _VSTD::fill_n(
+ _VSTD::copy(__buffer.begin(), __result.__exponent, __ctx.out()), __num_trailing_zeros, _CharT('0')));
+
+ return _VSTD::fill_n(
+ _VSTD::copy(__buffer.begin(), __result.__last, __ctx.out()), __num_trailing_zeros, _CharT('0'));
}
- /// Fills the buffer with the data based on the requested formatting.
- ///
- /// This function, when needed, turns the characters to upper case and
- /// determines the "interesting" locations which are returned to the caller.
- ///
- /// This means the caller never has to convert the contents of the buffer to
- /// upper case or search for radix points and the location of the exponent.
- /// This gives a bit of overhead. The original code didn't do that, but due
- /// to the number of possible additional work needed to turn this number to
- /// the proper output the code was littered with tests for upper cases and
- /// searches for radix points and exponents.
- /// - When a precision larger than the type's precision is selected
- /// additional zero characters need to be written before the exponent.
- /// - alternate form needs to add a radix point when not present.
- /// - localization needs to do grouping in the integral part.
- template <class _Fp, class _Tp>
- // TODO FMT _Fp should just be _Tp when to_chars has proper long double support.
- _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer(__float_buffer<_Fp>& __buffer, _Tp __value, bool __negative,
- bool __has_precision) {
- char* __first = __insert_sign(__buffer.begin(), __negative, this->__sign);
- switch (this->__type) {
- case _Flags::_Type::__default:
- return __format_spec::__format_buffer_default(__buffer, __value, __first);
-
- case _Flags::_Type::__float_hexadecimal_lower_case:
- return __format_spec::__format_buffer_hexadecimal_lower_case(
- __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first);
-
- case _Flags::_Type::__float_hexadecimal_upper_case:
- return __format_spec::__format_buffer_hexadecimal_upper_case(
- __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first);
-
- case _Flags::_Type::__scientific_lower_case:
- return __format_spec::__format_buffer_scientific_lower_case(__buffer, __value, __buffer.__precision(), __first);
+ auto __out_it = __ctx.out();
+ char* __first = __buffer.begin();
+ if (__specs.__alignment_ == __format_spec::__alignment ::__zero_padding) {
+ // When there is a sign output it before the padding. Note the __size
+ // doesn't need any adjustment, regardless whether the sign is written
+ // here or in __formatter::__write.
+ if (__first != __result.__integral)
+ *__out_it++ = *__first++;
+ // After the sign is written, zero padding is the same a right alignment
+ // with '0'.
+ __specs.__alignment_ = __format_spec::__alignment::__right;
+ __specs.__fill_ = _CharT('0');
+ }
- case _Flags::_Type::__scientific_upper_case:
- return __format_spec::__format_buffer_scientific_upper_case(__buffer, __value, __buffer.__precision(), __first);
+ if (__num_trailing_zeros)
+ return __formatter::__write_using_trailing_zeros(
+ __first, __result.__last, _VSTD::move(__out_it), __specs, __size, __result.__exponent, __num_trailing_zeros);
- case _Flags::_Type::__fixed_lower_case:
- case _Flags::_Type::__fixed_upper_case:
- return __format_spec::__format_buffer_fixed(__buffer, __value, __buffer.__precision(), __first);
+ return __formatter::__write(__first, __result.__last, _VSTD::move(__out_it), __specs, __size);
+}
- case _Flags::_Type::__general_lower_case:
- return __format_spec::__format_buffer_general_lower_case(__buffer, __value, __buffer.__precision(), __first);
+} // namespace __formatter
- case _Flags::_Type::__general_upper_case:
- return __format_spec::__format_buffer_general_upper_case(__buffer, __value, __buffer.__precision(), __first);
+template <__formatter::__char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS __formatter_floating_point {
+public:
+ _LIBCPP_HIDE_FROM_ABI constexpr auto
+ parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
+ auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_floating_point);
+ __format_spec::__process_parsed_floating_point(__parser_);
+ return __result;
+ }
- default:
- _LIBCPP_ASSERT(false, "The parser should have validated the type");
- __libcpp_unreachable();
- }
+ template <floating_point _Tp>
+ _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) const -> decltype(__ctx.out()) {
+ return __formatter::__format_floating_point(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx));
}
-};
-} //namespace __format_spec
+ __format_spec::__parser<_CharT> __parser_;
+};
template <__formatter::__char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<float, _CharT>
- : public __format_spec::__formatter_floating_point<_CharT> {};
+ : public __formatter_floating_point<_CharT> {};
template <__formatter::__char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<double, _CharT>
- : public __format_spec::__formatter_floating_point<_CharT> {};
+ : public __formatter_floating_point<_CharT> {};
template <__formatter::__char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long double, _CharT>
- : public __format_spec::__formatter_floating_point<_CharT> {};
+ : public __formatter_floating_point<_CharT> {};
#endif //_LIBCPP_STD_VER > 17
diff --git a/libcxx/include/__format/formatter_integer.h b/libcxx/include/__format/formatter_integer.h
index 5d11f8d1d990..0281b4f2fa67 100644
--- a/libcxx/include/__format/formatter_integer.h
+++ b/libcxx/include/__format/formatter_integer.h
@@ -13,23 +13,18 @@
#include <__availability>
#include <__concepts/arithmetic.h>
#include <__config>
-#include <__format/format_error.h> // TODO FMT Remove after adding 128-bit support
#include <__format/format_fwd.h>
#include <__format/format_parse_context.h>
#include <__format/formatter.h>
#include <__format/formatter_integral.h>
#include <__format/formatter_output.h>
#include <__format/parser_std_format_spec.h>
-#include <limits> // TODO FMT Remove after adding 128-bit support
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
-_LIBCPP_PUSH_MACROS // TODO FMT Remove after adding 128-bit support
-#include <__undef_macros>
-
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
@@ -79,18 +74,7 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long long, _Ch
# ifndef _LIBCPP_HAS_NO_INT128
template <__formatter::__char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__int128_t, _CharT>
- : public __formatter_integer<_CharT> {
- using _Base = __formatter_integer<_CharT>;
-
- _LIBCPP_HIDE_FROM_ABI auto format(__int128_t __value, auto& __ctx) const -> decltype(__ctx.out()) {
- // TODO FMT Implement full 128 bit support.
- using _To = long long;
- if (__value < numeric_limits<_To>::min() || __value > numeric_limits<_To>::max())
- std::__throw_format_error("128-bit value is outside of implemented range");
-
- return _Base::format(static_cast<_To>(__value), __ctx);
- }
-};
+ : public __formatter_integer<_CharT> {};
# endif
// Unsigned integral types.
@@ -112,24 +96,11 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long
# ifndef _LIBCPP_HAS_NO_INT128
template <__formatter::__char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__uint128_t, _CharT>
- : public __formatter_integer<_CharT> {
- using _Base = __formatter_integer<_CharT>;
-
- _LIBCPP_HIDE_FROM_ABI auto format(__uint128_t __value, auto& __ctx) const -> decltype(__ctx.out()) {
- // TODO FMT Implement full 128 bit support.
- using _To = unsigned long long;
- if (__value < numeric_limits<_To>::min() || __value > numeric_limits<_To>::max())
- std::__throw_format_error("128-bit value is outside of implemented range");
-
- return _Base::format(static_cast<_To>(__value), __ctx);
- }
-};
+ : public __formatter_integer<_CharT> {};
# endif
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
-_LIBCPP_POP_MACROS
-
#endif // _LIBCPP___FORMAT_FORMATTER_INTEGER_H
diff --git a/libcxx/include/__format/formatter_integral.h b/libcxx/include/__format/formatter_integral.h
index 4ad6de0ec66f..d6fa5ec18eb8 100644
--- a/libcxx/include/__format/formatter_integral.h
+++ b/libcxx/include/__format/formatter_integral.h
@@ -207,10 +207,6 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer(
char* __end,
const char* __prefix,
int __base) -> decltype(__ctx.out()) {
- _LIBCPP_ASSERT(
- __specs.__alignment_ != __format_spec::__alignment::__default,
- "the caller should adjust the default to the value required by the type");
-
char* __first = __formatter::__insert_sign(__begin, __negative, __specs.__std_.__sign_);
if (__specs.__std_.__alternate_form_ && __prefix)
while (*__prefix)
@@ -280,6 +276,7 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer(
return __formatter::__format_integer(
__value, __ctx, __specs, __negative, __array.begin(), __array.end(), __value != 0 ? "0" : nullptr, 8);
}
+ case __format_spec::__type::__default:
case __format_spec::__type::__decimal: {
array<char, __formatter::__buffer_size<decltype(__value), 10>()> __array;
return __formatter::__format_integer(
diff --git a/libcxx/include/__format/formatter_output.h b/libcxx/include/__format/formatter_output.h
index ab016f6f1610..c59cbbeeb5dd 100644
--- a/libcxx/include/__format/formatter_output.h
+++ b/libcxx/include/__format/formatter_output.h
@@ -33,8 +33,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace __formatter {
-_LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char c) {
- switch (c) {
+_LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char __c) {
+ switch (__c) {
case 'a':
return 'A';
case 'b':
@@ -48,27 +48,22 @@ _LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char c) {
case 'f':
return 'F';
}
- return c;
+ return __c;
}
-// TODO FMT remove _v2 suffix.
-struct _LIBCPP_TYPE_VIS __padding_size_result_v2 {
+struct _LIBCPP_TYPE_VIS __padding_size_result {
size_t __before_;
size_t __after_;
};
-// TODO FMT remove _v2 suffix.
-_LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result_v2 __padding_size_v2(size_t __size, size_t __width,
- __format_spec::__alignment __align) {
+_LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result
+__padding_size(size_t __size, size_t __width, __format_spec::__alignment __align) {
_LIBCPP_ASSERT(__width > __size, "don't call this function when no padding is required");
- _LIBCPP_ASSERT(__align != __format_spec::__alignment::__default,
- "the caller should adjust the default to the value required by the type");
_LIBCPP_ASSERT(__align != __format_spec::__alignment::__zero_padding,
"the caller should have handled the zero-padding");
size_t __fill = __width - __size;
switch (__align) {
- case __format_spec::__alignment::__default:
case __format_spec::__alignment::__zero_padding:
__libcpp_unreachable();
@@ -83,6 +78,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result_v2 __padding_size_v2(size_
size_t __after = __fill - __before;
return {__before, __after};
}
+ case __format_spec::__alignment::__default:
case __format_spec::__alignment::__right:
return {__fill, 0};
}
@@ -93,14 +89,11 @@ template <class _OutIt, class _CharT>
_LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, const char* __begin, const char* __first,
const char* __last, string&& __grouping, _CharT __sep,
__format_spec::__parsed_specifications<_CharT> __specs) {
- _LIBCPP_ASSERT(__specs.__alignment_ != __format_spec::__alignment::__default,
- "the caller should adjust the default to the value required by the type");
-
int __size = (__first - __begin) + // [sign][prefix]
(__last - __first) + // data
(__grouping.size() - 1); // number of separator characters
- __padding_size_result_v2 __padding = {0, 0};
+ __padding_size_result __padding = {0, 0};
if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) {
// Write [sign][prefix].
__out_it = _VSTD::copy(__begin, __first, _VSTD::move(__out_it));
@@ -113,7 +106,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, c
} else {
if (__specs.__width_ > __size) {
// Determine padding and write padding.
- __padding = __padding_size_v2(__size, __specs.__width_, __specs.__alignment_);
+ __padding = __padding_size(__size, __specs.__width_, __specs.__alignment_);
__out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
}
@@ -189,8 +182,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write(const _CharT* __first, const _CharT* __last,
if (__size >= __specs.__width_)
return _VSTD::copy(__first, __last, _VSTD::move(__out_it));
- __padding_size_result_v2 __padding =
- __formatter::__padding_size_v2(__size, __specs.__width_, __specs.__std_.__alignment_);
+ __padding_size_result __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__std_.__alignment_);
__out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
__out_it = _VSTD::copy(__first, __last, _VSTD::move(__out_it));
return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
@@ -216,12 +208,41 @@ _LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _Cha
if (__size >= __specs.__width_)
return _VSTD::transform(__first, __last, _VSTD::move(__out_it), __op);
- __padding_size_result_v2 __padding = __padding_size_v2(__size, __specs.__width_, __specs.__alignment_);
+ __padding_size_result __padding = __padding_size(__size, __specs.__width_, __specs.__alignment_);
__out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
__out_it = _VSTD::transform(__first, __last, _VSTD::move(__out_it), __op);
return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
}
+/// Writes additional zero's for the precision before the exponent.
+/// This is used when the precision requested in the format string is larger
+/// than the maximum precision of the floating-point type. These precision
+/// digits are always 0.
+///
+/// \param __exponent The location of the exponent character.
+/// \param __num_trailing_zeros The number of 0's to write before the exponent
+/// character.
+template <class _CharT, class _ParserCharT>
+_LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros(
+ const _CharT* __first,
+ const _CharT* __last,
+ output_iterator<const _CharT&> auto __out_it,
+ __format_spec::__parsed_specifications<_ParserCharT> __specs,
+ size_t __size,
+ const _CharT* __exponent,
+ size_t __num_trailing_zeros) -> decltype(__out_it) {
+ _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
+ _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used");
+
+ __padding_size_result __padding =
+ __padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_);
+ __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
+ __out_it = _VSTD::copy(__first, __exponent, _VSTD::move(__out_it));
+ __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0'));
+ __out_it = _VSTD::copy(__exponent, __last, _VSTD::move(__out_it));
+ return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
+}
+
# ifndef _LIBCPP_HAS_NO_UNICODE
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI auto __write_unicode_no_precision(basic_string_view<_CharT> __str,
diff --git a/libcxx/include/__format/parser_std_format_spec.h b/libcxx/include/__format/parser_std_format_spec.h
index 739bdf457e40..034fc55a44dc 100644
--- a/libcxx/include/__format/parser_std_format_spec.h
+++ b/libcxx/include/__format/parser_std_format_spec.h
@@ -44,168 +44,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace __format_spec {
-/**
- * Contains the flags for the std-format-spec.
- *
- * Some format-options can only be used for specific C++ types and may depend on
- * the selected format-type.
- * * The C++type filtering can be done using the proper policies for
- * @ref __parser_std.
- * * The format-type filtering needs to be done post parsing in the parser
- * derived from @ref __parser_std.
- */
-_LIBCPP_PACKED_BYTE_FOR_AIX
-class _LIBCPP_TYPE_VIS _Flags {
-public:
- enum class _LIBCPP_ENUM_VIS _Alignment : uint8_t {
- /**
- * No alignment is set in the format string.
- *
- * Zero-padding is ignored when an alignment is selected.
- * The default alignment depends on the selected format-type.
- */
- __default,
- __left,
- __center,
- __right
- };
- enum class _LIBCPP_ENUM_VIS _Sign : uint8_t {
- /**
- * No sign is set in the format string.
- *
- * The sign isn't allowed for certain format-types. By using this value
- * it's possible to detect whether or not the user explicitly set the sign
- * flag. For formatting purposes it behaves the same as @ref __minus.
- */
- __default,
- __minus,
- __plus,
- __space
- };
-
- _Alignment __alignment : 2 {_Alignment::__default};
- _Sign __sign : 2 {_Sign::__default};
- uint8_t __alternate_form : 1 {false};
- uint8_t __zero_padding : 1 {false};
- uint8_t __locale_specific_form : 1 {false};
-
- enum class _LIBCPP_ENUM_VIS _Type : uint8_t {
- __default,
- __string,
- __binary_lower_case,
- __binary_upper_case,
- __octal,
- __decimal,
- __hexadecimal_lower_case,
- __hexadecimal_upper_case,
- __pointer,
- __char,
- __float_hexadecimal_lower_case,
- __float_hexadecimal_upper_case,
- __scientific_lower_case,
- __scientific_upper_case,
- __fixed_lower_case,
- __fixed_upper_case,
- __general_lower_case,
- __general_upper_case
- };
-
- _Type __type{_Type::__default};
-};
-_LIBCPP_PACKED_BYTE_FOR_AIX_END
-
-namespace __detail {
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr bool
-__parse_alignment(_CharT __c, _Flags& __flags) noexcept {
- switch (__c) {
- case _CharT('<'):
- __flags.__alignment = _Flags::_Alignment::__left;
- return true;
-
- case _CharT('^'):
- __flags.__alignment = _Flags::_Alignment::__center;
- return true;
-
- case _CharT('>'):
- __flags.__alignment = _Flags::_Alignment::__right;
- return true;
- }
- return false;
-}
-} // namespace __detail
-
-template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS __parser_fill_align {
-public:
- // TODO FMT The standard doesn't specify this character is a Unicode
- // character. Validate what fmt and MSVC have implemented.
- _CharT __fill{_CharT(' ')};
-
-protected:
- _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
- __parse(const _CharT* __begin, const _CharT* __end, _Flags& __flags) {
- _LIBCPP_ASSERT(__begin != __end,
- "When called with an empty input the function will cause "
- "undefined behavior by evaluating data not in the input");
- if (__begin + 1 != __end) {
- if (__detail::__parse_alignment(*(__begin + 1), __flags)) {
- if (*__begin == _CharT('{') || *__begin == _CharT('}'))
- __throw_format_error(
- "The format-spec fill field contains an invalid character");
- __fill = *__begin;
- return __begin + 2;
- }
- }
-
- if (__detail::__parse_alignment(*__begin, __flags))
- return __begin + 1;
-
- return __begin;
- }
-};
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-__parse_sign(const _CharT* __begin, _Flags& __flags) noexcept {
- switch (*__begin) {
- case _CharT('-'):
- __flags.__sign = _Flags::_Sign::__minus;
- break;
- case _CharT('+'):
- __flags.__sign = _Flags::_Sign::__plus;
- break;
- case _CharT(' '):
- __flags.__sign = _Flags::_Sign::__space;
- break;
- default:
- return __begin;
- }
- return __begin + 1;
-}
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-__parse_alternate_form(const _CharT* __begin, _Flags& __flags) noexcept {
- if (*__begin == _CharT('#')) {
- __flags.__alternate_form = true;
- ++__begin;
- }
-
- return __begin;
-}
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-__parse_zero_padding(const _CharT* __begin, _Flags& __flags) noexcept {
- if (*__begin == _CharT('0')) {
- __flags.__zero_padding = true;
- ++__begin;
- }
-
- return __begin;
-}
-
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result< _CharT>
__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
@@ -226,7 +64,7 @@ __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
template <class _Context>
_LIBCPP_HIDE_FROM_ABI constexpr uint32_t
-__substitute_arg_id(basic_format_arg<_Context> _Arg) {
+__substitute_arg_id(basic_format_arg<_Context> __format_arg) {
return visit_format_arg(
[](auto __arg) -> uint32_t {
using _Type = decltype(__arg);
@@ -250,685 +88,9 @@ __substitute_arg_id(basic_format_arg<_Context> _Arg) {
__throw_format_error("A format-spec arg-id replacement argument "
"isn't an integral type");
},
- _Arg);
-}
-
-class _LIBCPP_TYPE_VIS __parser_width {
-public:
- /** Contains a width or an arg-id. */
- uint32_t __width : 31 {0};
- /** Determines whether the value stored is a width or an arg-id. */
- uint32_t __width_as_arg : 1 {0};
-
- /**
- * Does the supplied width field contain an arg-id?
- *
- * If @c true the formatter needs to call @ref __substitute_width_arg_id.
- */
- constexpr bool __width_needs_substitution() const noexcept { return __width_as_arg; }
-
-protected:
- /**
- * Does the supplied std-format-spec contain a width field?
- *
- * When the field isn't present there's no padding required. This can be used
- * to optimize the formatting.
- */
- constexpr bool __has_width_field() const noexcept { return __width_as_arg || __width; }
-
- template <class _CharT>
- _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
- __parse(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
- if (*__begin == _CharT('0'))
- __throw_format_error(
- "A format-spec width field shouldn't have a leading zero");
-
- if (*__begin == _CharT('{')) {
- __format::__parse_number_result __r =
- __parse_arg_id(++__begin, __end, __parse_ctx);
- __width = __r.__value;
- __width_as_arg = 1;
- return __r.__ptr;
- }
-
- if (*__begin < _CharT('0') || *__begin > _CharT('9'))
- return __begin;
-
- __format::__parse_number_result __r =
- __format::__parse_number(__begin, __end);
- __width = __r.__value;
- _LIBCPP_ASSERT(__width != 0,
- "A zero value isn't allowed and should be impossible, "
- "due to validations in this function");
- return __r.__ptr;
- }
-
- _LIBCPP_HIDE_FROM_ABI constexpr void __substitute_width_arg_id(auto __arg) {
- _LIBCPP_ASSERT(__width_as_arg == 1,
- "Substitute width called when no substitution is required");
-
- // The clearing of the flag isn't required but looks better when debugging
- // the code.
- __width_as_arg = 0;
- __width = __substitute_arg_id(__arg);
- if (__width == 0)
- __throw_format_error(
- "A format-spec width field replacement should have a positive value");
- }
-};
-
-class _LIBCPP_TYPE_VIS __parser_precision {
-public:
- /** Contains a precision or an arg-id. */
- uint32_t __precision : 31 {__format::__number_max};
- /**
- * Determines whether the value stored is a precision or an arg-id.
- *
- * @note Since @ref __precision == @ref __format::__number_max is a valid
- * value, the default value contains an arg-id of INT32_MAX. (This number of
- * arguments isn't supported by compilers.) This is used to detect whether
- * the std-format-spec contains a precision field.
- */
- uint32_t __precision_as_arg : 1 {1};
-
- /**
- * Does the supplied precision field contain an arg-id?
- *
- * If @c true the formatter needs to call @ref __substitute_precision_arg_id.
- */
- constexpr bool __precision_needs_substitution() const noexcept {
- return __precision_as_arg && __precision != __format::__number_max;
- }
-
-protected:
- /**
- * Does the supplied std-format-spec contain a precision field?
- *
- * When the field isn't present there's no truncating required. This can be
- * used to optimize the formatting.
- */
- constexpr bool __has_precision_field() const noexcept {
-
- return __precision_as_arg == 0 || // Contains a value?
- __precision != __format::__number_max; // The arg-id is valid?
- }
-
- template <class _CharT>
- _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
- __parse(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
- if (*__begin != _CharT('.'))
- return __begin;
-
- ++__begin;
- if (__begin == __end)
- __throw_format_error("End of input while parsing format-spec precision");
-
- if (*__begin == _CharT('{')) {
- __format::__parse_number_result __arg_id =
- __parse_arg_id(++__begin, __end, __parse_ctx);
- _LIBCPP_ASSERT(__arg_id.__value != __format::__number_max,
- "Unsupported number of arguments, since this number of "
- "arguments is used a special value");
- __precision = __arg_id.__value;
- return __arg_id.__ptr;
- }
-
- if (*__begin < _CharT('0') || *__begin > _CharT('9'))
- __throw_format_error(
- "The format-spec precision field doesn't contain a value or arg-id");
-
- __format::__parse_number_result __r =
- __format::__parse_number(__begin, __end);
- __precision = __r.__value;
- __precision_as_arg = 0;
- return __r.__ptr;
- }
-
- _LIBCPP_HIDE_FROM_ABI constexpr void __substitute_precision_arg_id(
- auto __arg) {
- _LIBCPP_ASSERT(
- __precision_as_arg == 1 && __precision != __format::__number_max,
- "Substitute precision called when no substitution is required");
-
- // The clearing of the flag isn't required but looks better when debugging
- // the code.
- __precision_as_arg = 0;
- __precision = __substitute_arg_id(__arg);
- }
-};
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-__parse_locale_specific_form(const _CharT* __begin, _Flags& __flags) noexcept {
- if (*__begin == _CharT('L')) {
- __flags.__locale_specific_form = true;
- ++__begin;
- }
-
- return __begin;
-}
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-__parse_type(const _CharT* __begin, _Flags& __flags) {
-
- // Determines the type. It does not validate whether the selected type is
- // valid. Most formatters have optional fields that are only allowed for
- // certain types. These parsers need to do validation after the type has
- // been parsed. So its easier to implement the validation for all types in
- // the specific parse function.
- switch (*__begin) {
- case 'A':
- __flags.__type = _Flags::_Type::__float_hexadecimal_upper_case;
- break;
- case 'B':
- __flags.__type = _Flags::_Type::__binary_upper_case;
- break;
- case 'E':
- __flags.__type = _Flags::_Type::__scientific_upper_case;
- break;
- case 'F':
- __flags.__type = _Flags::_Type::__fixed_upper_case;
- break;
- case 'G':
- __flags.__type = _Flags::_Type::__general_upper_case;
- break;
- case 'X':
- __flags.__type = _Flags::_Type::__hexadecimal_upper_case;
- break;
- case 'a':
- __flags.__type = _Flags::_Type::__float_hexadecimal_lower_case;
- break;
- case 'b':
- __flags.__type = _Flags::_Type::__binary_lower_case;
- break;
- case 'c':
- __flags.__type = _Flags::_Type::__char;
- break;
- case 'd':
- __flags.__type = _Flags::_Type::__decimal;
- break;
- case 'e':
- __flags.__type = _Flags::_Type::__scientific_lower_case;
- break;
- case 'f':
- __flags.__type = _Flags::_Type::__fixed_lower_case;
- break;
- case 'g':
- __flags.__type = _Flags::_Type::__general_lower_case;
- break;
- case 'o':
- __flags.__type = _Flags::_Type::__octal;
- break;
- case 'p':
- __flags.__type = _Flags::_Type::__pointer;
- break;
- case 's':
- __flags.__type = _Flags::_Type::__string;
- break;
- case 'x':
- __flags.__type = _Flags::_Type::__hexadecimal_lower_case;
- break;
- default:
- return __begin;
- }
- return ++__begin;
-}
-
-/**
- * Process the parsed alignment and zero-padding state of arithmetic types.
- *
- * [format.string.std]/13
- * If the 0 character and an align option both appear, the 0 character is
- * ignored.
- *
- * For the formatter a @ref __default alignment means zero-padding.
- */
-_LIBCPP_HIDE_FROM_ABI constexpr void __process_arithmetic_alignment(_Flags& __flags) {
- __flags.__zero_padding &= __flags.__alignment == _Flags::_Alignment::__default;
- if (!__flags.__zero_padding && __flags.__alignment == _Flags::_Alignment::__default)
- __flags.__alignment = _Flags::_Alignment::__right;
+ __format_arg);
}
-/**
- * The parser for the std-format-spec.
- *
- * [format.string.std]/1 specifies the std-format-spec:
- * fill-and-align sign # 0 width precision L type
- *
- * All these fields are optional. Whether these fields can be used depend on:
- * - The type supplied to the format string.
- * E.g. A string never uses the sign field so the field may not be set.
- * This constrain is validated by the parsers in this file.
- * - The supplied value for the optional type field.
- * E.g. A int formatted as decimal uses the sign field.
- * When formatted as a char the sign field may no longer be set.
- * This constrain isn't validated by the parsers in this file.
- *
- * The base classes are ordered to minimize the amount of padding.
- *
- * This implements the parser for the string types.
- */
-template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS __parser_string
- : public __parser_width, // provides __width(|as_arg)
- public __parser_precision, // provides __precision(|as_arg)
- public __parser_fill_align<_CharT>, // provides __fill and uses __flags
- public _Flags // provides __flags
-{
-public:
- using char_type = _CharT;
-
- _LIBCPP_HIDE_FROM_ABI constexpr __parser_string() {
- this->__alignment = _Flags::_Alignment::__left;
- }
-
- /**
- * The low-level std-format-spec parse function.
- *
- * @pre __begin points at the beginning of the std-format-spec. This means
- * directly after the ':'.
- * @pre The std-format-spec parses the entire input, or the first unmatched
- * character is a '}'.
- *
- * @returns The iterator pointing at the last parsed character.
- */
- _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx)
- -> decltype(__parse_ctx.begin()) {
- auto __it = __parse(__parse_ctx);
- __process_display_type();
- return __it;
- }
-
-private:
- /**
- * Parses the std-format-spec.
- *
- * @throws __throw_format_error When @a __parse_ctx contains an ill-formed
- * std-format-spec.
- *
- * @returns An iterator to the end of input or point at the closing '}'.
- */
- _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx)
- -> decltype(__parse_ctx.begin()) {
-
- auto __begin = __parse_ctx.begin();
- auto __end = __parse_ctx.end();
- if (__begin == __end)
- return __begin;
-
- __begin = __parser_fill_align<_CharT>::__parse(__begin, __end,
- static_cast<_Flags&>(*this));
- if (__begin == __end)
- return __begin;
-
- __begin = __parser_width::__parse(__begin, __end, __parse_ctx);
- if (__begin == __end)
- return __begin;
-
- __begin = __parser_precision::__parse(__begin, __end, __parse_ctx);
- if (__begin == __end)
- return __begin;
-
- __begin = __parse_type(__begin, static_cast<_Flags&>(*this));
-
- if (__begin != __end && *__begin != _CharT('}'))
- __throw_format_error(
- "The format-spec should consume the input or end with a '}'");
-
- return __begin;
- }
-
- /** Processes the parsed std-format-spec based on the parsed display type. */
- _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() {
- switch (this->__type) {
- case _Flags::_Type::__default:
- case _Flags::_Type::__string:
- break;
-
- default:
- __throw_format_error("The format-spec type has a type not supported for "
- "a string argument");
- }
- }
-};
-
-/**
- * The parser for the std-format-spec.
- *
- * This implements the parser for the integral types. This includes the
- * character type and boolean type.
- *
- * See @ref __parser_string.
- */
-template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS __parser_integral
- : public __parser_width, // provides __width(|as_arg)
- public __parser_fill_align<_CharT>, // provides __fill and uses __flags
- public _Flags // provides __flags
-{
-public:
- using char_type = _CharT;
-
-protected:
- /**
- * The low-level std-format-spec parse function.
- *
- * @pre __begin points at the beginning of the std-format-spec. This means
- * directly after the ':'.
- * @pre The std-format-spec parses the entire input, or the first unmatched
- * character is a '}'.
- *
- * @returns The iterator pointing at the last parsed character.
- */
- _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx)
- -> decltype(__parse_ctx.begin()) {
- auto __begin = __parse_ctx.begin();
- auto __end = __parse_ctx.end();
- if (__begin == __end)
- return __begin;
-
- __begin = __parser_fill_align<_CharT>::__parse(__begin, __end,
- static_cast<_Flags&>(*this));
- if (__begin == __end)
- return __begin;
-
- __begin = __parse_sign(__begin, static_cast<_Flags&>(*this));
- if (__begin == __end)
- return __begin;
-
- __begin = __parse_alternate_form(__begin, static_cast<_Flags&>(*this));
- if (__begin == __end)
- return __begin;
-
- __begin = __parse_zero_padding(__begin, static_cast<_Flags&>(*this));
- if (__begin == __end)
- return __begin;
-
- __begin = __parser_width::__parse(__begin, __end, __parse_ctx);
- if (__begin == __end)
- return __begin;
-
- __begin =
- __parse_locale_specific_form(__begin, static_cast<_Flags&>(*this));
- if (__begin == __end)
- return __begin;
-
- __begin = __parse_type(__begin, static_cast<_Flags&>(*this));
-
- if (__begin != __end && *__begin != _CharT('}'))
- __throw_format_error(
- "The format-spec should consume the input or end with a '}'");
-
- return __begin;
- }
-
- /** Handles the post-parsing updates for the integer types. */
- _LIBCPP_HIDE_FROM_ABI constexpr void __handle_integer() noexcept {
- __process_arithmetic_alignment(static_cast<_Flags&>(*this));
- }
-
- /**
- * Handles the post-parsing updates for the character types.
- *
- * Sets the alignment and validates the format flags set for a character type.
- *
- * At the moment the validation for a character and a Boolean behave the
- * same, but this may change in the future.
- * Specifically at the moment the locale-specific form is allowed for the
- * char output type, but it has no effect on the output.
- */
- _LIBCPP_HIDE_FROM_ABI constexpr void __handle_char() { __handle_bool(); }
-
- /**
- * Handles the post-parsing updates for the Boolean types.
- *
- * Sets the alignment and validates the format flags set for a Boolean type.
- */
- _LIBCPP_HIDE_FROM_ABI constexpr void __handle_bool() {
- if (this->__sign != _Flags::_Sign::__default)
- __throw_format_error("A sign field isn't allowed in this format-spec");
-
- if (this->__alternate_form)
- __throw_format_error(
- "An alternate form field isn't allowed in this format-spec");
-
- if (this->__zero_padding)
- __throw_format_error(
- "A zero-padding field isn't allowed in this format-spec");
-
- if (this->__alignment == _Flags::_Alignment::__default)
- this->__alignment = _Flags::_Alignment::__left;
- }
-};
-
-/**
- * The parser for the std-format-spec.
- *
- * This implements the parser for the floating-point types.
- *
- * See @ref __parser_string.
- */
-template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS __parser_floating_point
- : public __parser_width, // provides __width(|as_arg)
- public __parser_precision, // provides __precision(|as_arg)
- public __parser_fill_align<_CharT>, // provides __fill and uses __flags
- public _Flags // provides __flags
-{
-public:
- using char_type = _CharT;
-
- /**
- * The low-level std-format-spec parse function.
- *
- * @pre __begin points at the beginning of the std-format-spec. This means
- * directly after the ':'.
- * @pre The std-format-spec parses the entire input, or the first unmatched
- * character is a '}'.
- *
- * @returns The iterator pointing at the last parsed character.
- */
- _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx)
- -> decltype(__parse_ctx.begin()) {
- auto __it = __parse(__parse_ctx);
- __process_arithmetic_alignment(static_cast<_Flags&>(*this));
- __process_display_type();
- return __it;
- }
-protected:
- /**
- * The low-level std-format-spec parse function.
- *
- * @pre __begin points at the beginning of the std-format-spec. This means
- * directly after the ':'.
- * @pre The std-format-spec parses the entire input, or the first unmatched
- * character is a '}'.
- *
- * @returns The iterator pointing at the last parsed character.
- */
- _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx)
- -> decltype(__parse_ctx.begin()) {
- auto __begin = __parse_ctx.begin();
- auto __end = __parse_ctx.end();
- if (__begin == __end)
- return __begin;
-
- __begin = __parser_fill_align<_CharT>::__parse(__begin, __end,
- static_cast<_Flags&>(*this));
- if (__begin == __end)
- return __begin;
-
- __begin = __parse_sign(__begin, static_cast<_Flags&>(*this));
- if (__begin == __end)
- return __begin;
-
- __begin = __parse_alternate_form(__begin, static_cast<_Flags&>(*this));
- if (__begin == __end)
- return __begin;
-
- __begin = __parse_zero_padding(__begin, static_cast<_Flags&>(*this));
- if (__begin == __end)
- return __begin;
-
- __begin = __parser_width::__parse(__begin, __end, __parse_ctx);
- if (__begin == __end)
- return __begin;
-
- __begin = __parser_precision::__parse(__begin, __end, __parse_ctx);
- if (__begin == __end)
- return __begin;
-
- __begin =
- __parse_locale_specific_form(__begin, static_cast<_Flags&>(*this));
- if (__begin == __end)
- return __begin;
-
- __begin = __parse_type(__begin, static_cast<_Flags&>(*this));
-
- if (__begin != __end && *__begin != _CharT('}'))
- __throw_format_error(
- "The format-spec should consume the input or end with a '}'");
-
- return __begin;
- }
-
- /** Processes the parsed std-format-spec based on the parsed display type. */
- _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() {
- switch (this->__type) {
- case _Flags::_Type::__default:
- // When no precision specified then it keeps default since that
- // formatting differs from the other types.
- if (this->__has_precision_field())
- this->__type = _Flags::_Type::__general_lower_case;
- break;
- case _Flags::_Type::__float_hexadecimal_lower_case:
- case _Flags::_Type::__float_hexadecimal_upper_case:
- // Precision specific behavior will be handled later.
- break;
- case _Flags::_Type::__scientific_lower_case:
- case _Flags::_Type::__scientific_upper_case:
- case _Flags::_Type::__fixed_lower_case:
- case _Flags::_Type::__fixed_upper_case:
- case _Flags::_Type::__general_lower_case:
- case _Flags::_Type::__general_upper_case:
- if (!this->__has_precision_field()) {
- // Set the default precision for the call to to_chars.
- this->__precision = 6;
- this->__precision_as_arg = false;
- }
- break;
-
- default:
- __throw_format_error("The format-spec type has a type not supported for "
- "a floating-point argument");
- }
- }
-};
-
-/**
- * The parser for the std-format-spec.
- *
- * This implements the parser for the pointer types.
- *
- * See @ref __parser_string.
- */
-template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS __parser_pointer : public __parser_width, // provides __width(|as_arg)
- public __parser_fill_align<_CharT>, // provides __fill and uses __flags
- public _Flags // provides __flags
-{
-public:
- using char_type = _CharT;
-
- _LIBCPP_HIDE_FROM_ABI constexpr __parser_pointer() {
- // Implements LWG3612 Inconsistent pointer alignment in std::format.
- // The issue's current status is "Tentatively Ready" and libc++ status is
- // still experimental.
- //
- // TODO FMT Validate this with the final resolution of LWG3612.
- this->__alignment = _Flags::_Alignment::__right;
- }
-
- /**
- * The low-level std-format-spec parse function.
- *
- * @pre __begin points at the beginning of the std-format-spec. This means
- * directly after the ':'.
- * @pre The std-format-spec parses the entire input, or the first unmatched
- * character is a '}'.
- *
- * @returns The iterator pointing at the last parsed character.
- */
- _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) {
- auto __it = __parse(__parse_ctx);
- __process_display_type();
- return __it;
- }
-
-protected:
- /**
- * The low-level std-format-spec parse function.
- *
- * @pre __begin points at the beginning of the std-format-spec. This means
- * directly after the ':'.
- * @pre The std-format-spec parses the entire input, or the first unmatched
- * character is a '}'.
- *
- * @returns The iterator pointing at the last parsed character.
- */
- _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) {
- auto __begin = __parse_ctx.begin();
- auto __end = __parse_ctx.end();
- if (__begin == __end)
- return __begin;
-
- __begin = __parser_fill_align<_CharT>::__parse(__begin, __end, static_cast<_Flags&>(*this));
- if (__begin == __end)
- return __begin;
-
- // An integer presentation type isn't defined in the Standard.
- // Since a pointer is formatted as an integer it can be argued it's an
- // integer presentation type. However there are two LWG-issues asserting it
- // isn't an integer presentation type:
- // - LWG3612 Inconsistent pointer alignment in std::format
- // - LWG3644 std::format does not define "integer presentation type"
- //
- // There's a paper to make additional clarifications on the status of
- // formatting pointers and proposes additional fields to be valid. That
- // paper hasn't been reviewed by the Committee yet.
- // - P2510 Formatting pointers
- //
- // The current implementation assumes formatting pointers isn't covered by
- // "integer presentation type".
- // TODO FMT Apply the LWG-issues/papers after approval/rejection by the Committee.
-
- __begin = __parser_width::__parse(__begin, __end, __parse_ctx);
- if (__begin == __end)
- return __begin;
-
- __begin = __parse_type(__begin, static_cast<_Flags&>(*this));
-
- if (__begin != __end && *__begin != _CharT('}'))
- __throw_format_error("The format-spec should consume the input or end with a '}'");
-
- return __begin;
- }
-
- /** Processes the parsed std-format-spec based on the parsed display type. */
- _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() {
- switch (this->__type) {
- case _Flags::_Type::__default:
- this->__type = _Flags::_Type::__pointer;
- break;
- case _Flags::_Type::__pointer:
- break;
- default:
- __throw_format_error("The format-spec type has a type not supported for a pointer argument");
- }
- }
-};
-
/** Helper struct returned from @ref __get_string_alignment. */
template <class _CharT>
struct _LIBCPP_TEMPLATE_VIS __string_alignment {
@@ -1406,6 +568,13 @@ inline constexpr __fields __fields_integral{
.__zero_padding_ = true,
.__locale_specific_form_ = true,
.__type_ = true};
+inline constexpr __fields __fields_floating_point{
+ .__sign_ = true,
+ .__alternate_form_ = true,
+ .__zero_padding_ = true,
+ .__precision_ = true,
+ .__locale_specific_form_ = true,
+ .__type_ = true};
inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true};
inline constexpr __fields __fields_pointer{.__type_ = true};
@@ -1872,17 +1041,9 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_char(__parser<_CharT
}
template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_integer(__parser<_CharT>& __parser) {
- if (__parser.__alignment_ == __alignment::__default)
- __parser.__alignment_ = __alignment::__right;
-}
-
-template <class _CharT>
_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __parser) {
switch (__parser.__type_) {
case __format_spec::__type::__default:
- __parser.__type_ = __format_spec::__type::__string;
- [[fallthrough]];
case __format_spec::__type::__string:
__format_spec::__process_display_type_bool_string(__parser);
break;
@@ -1893,7 +1054,6 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __p
case __format_spec::__type::__decimal:
case __format_spec::__type::__hexadecimal_lower_case:
case __format_spec::__type::__hexadecimal_upper_case:
- __process_display_type_integer(__parser);
break;
default:
@@ -1905,8 +1065,6 @@ template <class _CharT>
_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __parser) {
switch (__parser.__type_) {
case __format_spec::__type::__default:
- __parser.__type_ = __format_spec::__type::__char;
- [[fallthrough]];
case __format_spec::__type::__char:
__format_spec::__process_display_type_char(__parser);
break;
@@ -1917,7 +1075,6 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __p
case __format_spec::__type::__decimal:
case __format_spec::__type::__hexadecimal_lower_case:
case __format_spec::__type::__hexadecimal_upper_case:
- __format_spec::__process_display_type_integer(__parser);
break;
default:
@@ -1929,15 +1086,12 @@ template <class _CharT>
_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& __parser) {
switch (__parser.__type_) {
case __format_spec::__type::__default:
- __parser.__type_ = __format_spec::__type::__decimal;
- [[fallthrough]];
case __format_spec::__type::__binary_lower_case:
case __format_spec::__type::__binary_upper_case:
case __format_spec::__type::__octal:
case __format_spec::__type::__decimal:
case __format_spec::__type::__hexadecimal_lower_case:
case __format_spec::__type::__hexadecimal_upper_case:
- __format_spec::__process_display_type_integer(__parser);
break;
case __format_spec::__type::__char:
@@ -1949,6 +1103,35 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>&
}
}
+template <class _CharT>
+_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_CharT>& __parser) {
+ switch (__parser.__type_) {
+ case __format_spec::__type::__default:
+ // When no precision specified then it keeps default since that
+ // formatting differs from the other types.
+ if (__parser.__precision_as_arg_ || __parser.__precision_ != -1)
+ __parser.__type_ = __format_spec::__type::__general_lower_case;
+ break;
+ case __format_spec::__type::__hexfloat_lower_case:
+ case __format_spec::__type::__hexfloat_upper_case:
+ // Precision specific behavior will be handled later.
+ break;
+ case __format_spec::__type::__scientific_lower_case:
+ case __format_spec::__type::__scientific_upper_case:
+ case __format_spec::__type::__fixed_lower_case:
+ case __format_spec::__type::__fixed_upper_case:
+ case __format_spec::__type::__general_lower_case:
+ case __format_spec::__type::__general_upper_case:
+ if (!__parser.__precision_as_arg_ && __parser.__precision_ == -1)
+ // Set the default precision for the call to to_chars.
+ __parser.__precision_ = 6;
+ break;
+
+ default:
+ std::__throw_format_error("The format-spec type has a type not supported for a floating-point argument");
+ }
+}
+
_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_pointer(__format_spec::__type __type) {
switch (__type) {
case __format_spec::__type::__default:
diff --git a/libcxx/include/__functional/default_searcher.h b/libcxx/include/__functional/default_searcher.h
index 05fb23d7c3c4..8e37082b6bed 100644
--- a/libcxx/include/__functional/default_searcher.h
+++ b/libcxx/include/__functional/default_searcher.h
@@ -12,6 +12,7 @@
#include <__algorithm/search.h>
#include <__config>
+#include <__functional/identity.h>
#include <__functional/operations.h>
#include <__iterator/iterator_traits.h>
#include <__utility/pair.h>
@@ -38,16 +39,15 @@ public:
pair<_ForwardIterator2, _ForwardIterator2>
operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const
{
- return _VSTD::__search(__f, __l, __first_, __last_, __pred_,
- typename iterator_traits<_ForwardIterator>::iterator_category(),
- typename iterator_traits<_ForwardIterator2>::iterator_category());
+ auto __proj = __identity();
+ return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj);
}
private:
_ForwardIterator __first_;
_ForwardIterator __last_;
_BinaryPredicate __pred_;
- };
+};
#endif // _LIBCPP_STD_VER > 14
diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h
index 312443b67c3b..db3af6e24101 100644
--- a/libcxx/include/__functional/function.h
+++ b/libcxx/include/__functional/function.h
@@ -390,9 +390,9 @@ template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
typedef __base<_Rp(_ArgTypes...)> __func;
__func* __f_;
- _LIBCPP_NO_CFI static __func* __as_base(void* p)
+ _LIBCPP_NO_CFI static __func* __as_base(void* __p)
{
- return reinterpret_cast<__func*>(p);
+ return reinterpret_cast<__func*>(__p);
}
public:
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index 20223014432f..6123a310ad63 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -178,16 +178,14 @@ struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {
template <class _Up>
_LIBCPP_INLINE_VISIBILITY
- static typename enable_if<__is_same_uncvref<_Up, __node_value_type>::value,
- __container_value_type const&>::type
+ static __enable_if_t<__is_same_uncvref<_Up, __node_value_type>::value, __container_value_type const&>
__get_value(_Up& __t) {
return __t.__get_value();
}
template <class _Up>
_LIBCPP_INLINE_VISIBILITY
- static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
- __container_value_type const&>::type
+ static __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, __container_value_type const&>
__get_value(_Up& __t) {
return __t;
}
@@ -1049,10 +1047,8 @@ public:
template <class _First, class _Second>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<
- __can_extract_map_key<_First, key_type, __container_value_type>::value,
- pair<iterator, bool>
- >::type __emplace_unique(_First&& __f, _Second&& __s) {
+ __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, pair<iterator, bool> >
+ __emplace_unique(_First&& __f, _Second&& __s) {
return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
_VSTD::forward<_Second>(__s));
}
@@ -1096,9 +1092,7 @@ public:
return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x));
}
- template <class _Pp, class = typename enable_if<
- !__is_same_uncvref<_Pp, __container_value_type>::value
- >::type>
+ template <class _Pp, class = __enable_if_t<!__is_same_uncvref<_Pp, __container_value_type>::value> >
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> __insert_unique(_Pp&& __x) {
return __emplace_unique(_VSTD::forward<_Pp>(__x));
@@ -1152,9 +1146,16 @@ public:
#endif
void clear() _NOEXCEPT;
- void rehash(size_type __n);
- _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n)
- {rehash(static_cast<size_type>(ceil(__n / max_load_factor())));}
+ _LIBCPP_INLINE_VISIBILITY void __rehash_unique(size_type __n) { __rehash<true>(__n); }
+ _LIBCPP_INLINE_VISIBILITY void __rehash_multi(size_type __n) { __rehash<false>(__n); }
+ _LIBCPP_INLINE_VISIBILITY void __reserve_unique(size_type __n)
+ {
+ __rehash_unique(static_cast<size_type>(ceil(__n / max_load_factor())));
+ }
+ _LIBCPP_INLINE_VISIBILITY void __reserve_multi(size_type __n)
+ {
+ __rehash_multi(static_cast<size_type>(ceil(__n / max_load_factor())));
+ }
_LIBCPP_INLINE_VISIBILITY
size_type bucket_count() const _NOEXCEPT
@@ -1291,7 +1292,8 @@ public:
#endif // _LIBCPP_ENABLE_DEBUG_MODE
private:
- void __rehash(size_type __n);
+ template <bool _UniqueKeys> void __rehash(size_type __n);
+ template <bool _UniqueKeys> void __do_rehash(size_type __n);
template <class ..._Args>
__node_holder __construct_node(_Args&& ...__args);
@@ -1796,7 +1798,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(
}
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
- rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
+ __rehash_unique(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
size_type(ceil(float(size() + 1) / max_load_factor()))));
}
return nullptr;
@@ -1868,7 +1870,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare(
size_type __bc = bucket_count();
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
- rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
+ __rehash_multi(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
size_type(ceil(float(size() + 1) / max_load_factor()))));
__bc = bucket_count();
}
@@ -1962,7 +1964,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
size_type __bc = bucket_count();
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
- rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
+ __rehash_multi(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
size_type(ceil(float(size() + 1) / max_load_factor()))));
__bc = bucket_count();
}
@@ -2010,7 +2012,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const&
__node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...);
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
- rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
+ __rehash_unique(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
size_type(ceil(float(size() + 1) / max_load_factor()))));
__bc = bucket_count();
__chash = __constrain_hash(__hash, __bc);
@@ -2213,8 +2215,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(
#endif // _LIBCPP_STD_VER > 14
template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <bool _UniqueKeys>
void
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n)
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n)
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
{
if (__n == 1)
@@ -2223,7 +2226,7 @@ _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
__n = __next_prime(__n);
size_type __bc = bucket_count();
if (__n > __bc)
- __rehash(__n);
+ __do_rehash<_UniqueKeys>(__n);
else if (__n < __bc)
{
__n = _VSTD::max<size_type>
@@ -2233,13 +2236,14 @@ _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
__next_prime(size_t(ceil(float(size()) / max_load_factor())))
);
if (__n < __bc)
- __rehash(__n);
+ __do_rehash<_UniqueKeys>(__n);
}
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <bool _UniqueKeys>
void
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc)
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc)
{
std::__debug_db_invalidate_all(this);
__pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
@@ -2274,11 +2278,14 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc)
else
{
__next_pointer __np = __cp;
- for (; __np->__next_ != nullptr &&
- key_eq()(__cp->__upcast()->__value_,
- __np->__next_->__upcast()->__value_);
- __np = __np->__next_)
- ;
+ if _LIBCPP_CONSTEXPR_AFTER_CXX14 (!_UniqueKeys)
+ {
+ for (; __np->__next_ != nullptr &&
+ key_eq()(__cp->__upcast()->__value_,
+ __np->__next_->__upcast()->__value_);
+ __np = __np->__next_)
+ ;
+ }
__pp->__next_ = __np->__next_;
__np->__next_ = __bucket_list_[__chash]->__next_;
__bucket_list_[__chash]->__next_ = __cp;
diff --git a/libcxx/include/__iterator/back_insert_iterator.h b/libcxx/include/__iterator/back_insert_iterator.h
index 7bbf5b09e0e5..e9f9f2abec2a 100644
--- a/libcxx/include/__iterator/back_insert_iterator.h
+++ b/libcxx/include/__iterator/back_insert_iterator.h
@@ -46,11 +46,11 @@ public:
typedef _Container container_type;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(const typename _Container::value_type& __value_)
- {container->push_back(__value_); return *this;}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(const typename _Container::value_type& __value)
+ {container->push_back(__value); return *this;}
#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(typename _Container::value_type&& __value_)
- {container->push_back(_VSTD::move(__value_)); return *this;}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(typename _Container::value_type&& __value)
+ {container->push_back(_VSTD::move(__value)); return *this;}
#endif // _LIBCPP_CXX03_LANG
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator*() {return *this;}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator++() {return *this;}
diff --git a/libcxx/include/__iterator/front_insert_iterator.h b/libcxx/include/__iterator/front_insert_iterator.h
index 69b2d32d077a..9c8ec0028298 100644
--- a/libcxx/include/__iterator/front_insert_iterator.h
+++ b/libcxx/include/__iterator/front_insert_iterator.h
@@ -46,11 +46,11 @@ public:
typedef _Container container_type;
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(const typename _Container::value_type& __value_)
- {container->push_front(__value_); return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(const typename _Container::value_type& __value)
+ {container->push_front(__value); return *this;}
#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(typename _Container::value_type&& __value_)
- {container->push_front(_VSTD::move(__value_)); return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(typename _Container::value_type&& __value)
+ {container->push_front(_VSTD::move(__value)); return *this;}
#endif // _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator*() {return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator++() {return *this;}
diff --git a/libcxx/include/__iterator/insert_iterator.h b/libcxx/include/__iterator/insert_iterator.h
index 8b313f2a85bb..b35d8bf16af9 100644
--- a/libcxx/include/__iterator/insert_iterator.h
+++ b/libcxx/include/__iterator/insert_iterator.h
@@ -57,11 +57,11 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator(_Container& __x, __insert_iterator_iter_t<_Container> __i)
: container(_VSTD::addressof(__x)), iter(__i) {}
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(const typename _Container::value_type& __value_)
- {iter = container->insert(iter, __value_); ++iter; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(const typename _Container::value_type& __value)
+ {iter = container->insert(iter, __value); ++iter; return *this;}
#ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(typename _Container::value_type&& __value_)
- {iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(typename _Container::value_type&& __value)
+ {iter = container->insert(iter, _VSTD::move(__value)); ++iter; return *this;}
#endif // _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator*() {return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++() {return *this;}
diff --git a/libcxx/include/__iterator/iterator_traits.h b/libcxx/include/__iterator/iterator_traits.h
index c3a5b7e0dd22..63525e230add 100644
--- a/libcxx/include/__iterator/iterator_traits.h
+++ b/libcxx/include/__iterator/iterator_traits.h
@@ -475,6 +475,18 @@ struct __is_exactly_cpp17_input_iterator
__has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value &&
!__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {};
+template <class _Tp>
+struct __is_exactly_cpp17_forward_iterator
+ : public integral_constant<bool,
+ __has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value &&
+ !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value> {};
+
+template <class _Tp>
+struct __is_exactly_cpp17_bidirectional_iterator
+ : public integral_constant<bool,
+ __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value &&
+ !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value> {};
+
template<class _InputIterator>
using __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
diff --git a/libcxx/include/__iterator/ostream_iterator.h b/libcxx/include/__iterator/ostream_iterator.h
index 76ae4614939f..d16f5a26ebaa 100644
--- a/libcxx/include/__iterator/ostream_iterator.h
+++ b/libcxx/include/__iterator/ostream_iterator.h
@@ -53,9 +53,9 @@ public:
: __out_stream_(_VSTD::addressof(__s)), __delim_(nullptr) {}
_LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT
: __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {}
- _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_)
+ _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value)
{
- *__out_stream_ << __value_;
+ *__out_stream_ << __value;
if (__delim_)
*__out_stream_ << __delim_;
return *this;
diff --git a/libcxx/include/__iterator/reverse_iterator.h b/libcxx/include/__iterator/reverse_iterator.h
index 89bda19effef..a915609dbe33 100644
--- a/libcxx/include/__iterator/reverse_iterator.h
+++ b/libcxx/include/__iterator/reverse_iterator.h
@@ -15,15 +15,20 @@
#include <__compare/three_way_comparable.h>
#include <__concepts/convertible_to.h>
#include <__config>
+#include <__iterator/advance.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iter_move.h>
#include <__iterator/iter_swap.h>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
#include <__iterator/prev.h>
#include <__iterator/readable_traits.h>
#include <__memory/addressof.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/subrange.h>
#include <__utility/move.h>
#include <type_traits>
@@ -136,7 +141,7 @@ public:
#if _LIBCPP_STD_VER > 17
_LIBCPP_INLINE_VISIBILITY
constexpr pointer operator->() const
- requires is_pointer_v<_Iter> || requires(const _Iter i) { i.operator->(); }
+ requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); }
{
if constexpr (is_pointer_v<_Iter>) {
return std::prev(current);
@@ -365,6 +370,16 @@ struct __rewrap_iter_impl<_ReverseWrapper<_OrigIter>, _UnwrappedIter> {
}
};
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+template <ranges::bidirectional_range _Range>
+_LIBCPP_HIDE_FROM_ABI constexpr ranges::
+ subrange<reverse_iterator<ranges::iterator_t<_Range>>, reverse_iterator<ranges::iterator_t<_Range>>>
+ __reverse_range(_Range&& __range) {
+ auto __first = ranges::begin(__range);
+ return {std::make_reverse_iterator(ranges::next(__first, ranges::end(__range))), std::make_reverse_iterator(__first)};
+}
+#endif
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
diff --git a/libcxx/include/__mutex_base b/libcxx/include/__mutex_base
index da056b6d1423..ac0d090b7d19 100644
--- a/libcxx/include/__mutex_base
+++ b/libcxx/include/__mutex_base
@@ -338,11 +338,7 @@ private:
template <class _Rep, class _Period>
inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
- is_floating_point<_Rep>::value,
- chrono::nanoseconds
->::type
+__enable_if_t<is_floating_point<_Rep>::value, chrono::nanoseconds>
__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d)
{
using namespace chrono;
@@ -365,11 +361,7 @@ __safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d)
template <class _Rep, class _Period>
inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
- !is_floating_point<_Rep>::value,
- chrono::nanoseconds
->::type
+__enable_if_t<!is_floating_point<_Rep>::value, chrono::nanoseconds>
__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d)
{
using namespace chrono;
diff --git a/libcxx/include/__numeric/iota.h b/libcxx/include/__numeric/iota.h
index b30e0e0a5484..b7127a11cb75 100644
--- a/libcxx/include/__numeric/iota.h
+++ b/libcxx/include/__numeric/iota.h
@@ -21,10 +21,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator, class _Tp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void
-iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_)
+iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
{
- for (; __first != __last; ++__first, (void) ++__value_)
- *__first = __value_;
+ for (; __first != __last; ++__first, (void) ++__value)
+ *__first = __value;
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__random/piecewise_constant_distribution.h b/libcxx/include/__random/piecewise_constant_distribution.h
index a33ab0720062..9c9e14b16d6e 100644
--- a/libcxx/include/__random/piecewise_constant_distribution.h
+++ b/libcxx/include/__random/piecewise_constant_distribution.h
@@ -43,8 +43,8 @@ public:
param_type();
template<class _InputIteratorB, class _InputIteratorW>
- param_type(_InputIteratorB __fB, _InputIteratorB __lB,
- _InputIteratorW __fW);
+ param_type(_InputIteratorB __f_b, _InputIteratorB __l_b,
+ _InputIteratorW __f_w);
#ifndef _LIBCPP_CXX03_LANG
template<class _UnaryOperation>
param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
@@ -94,10 +94,10 @@ public:
piecewise_constant_distribution() {}
template<class _InputIteratorB, class _InputIteratorW>
_LIBCPP_INLINE_VISIBILITY
- piecewise_constant_distribution(_InputIteratorB __fB,
- _InputIteratorB __lB,
- _InputIteratorW __fW)
- : __p_(__fB, __lB, __fW) {}
+ piecewise_constant_distribution(_InputIteratorB __f_b,
+ _InputIteratorB __l_b,
+ _InputIteratorW __f_w)
+ : __p_(__f_b, __l_b, __f_w) {}
#ifndef _LIBCPP_CXX03_LANG
template<class _UnaryOperation>
@@ -215,8 +215,8 @@ piecewise_constant_distribution<_RealType>::param_type::param_type()
template<class _RealType>
template<class _InputIteratorB, class _InputIteratorW>
piecewise_constant_distribution<_RealType>::param_type::param_type(
- _InputIteratorB __fB, _InputIteratorB __lB, _InputIteratorW __fW)
- : __b_(__fB, __lB)
+ _InputIteratorB __f_b, _InputIteratorB __l_b, _InputIteratorW __f_w)
+ : __b_(__f_b, __l_b)
{
if (__b_.size() < 2)
{
@@ -229,8 +229,8 @@ piecewise_constant_distribution<_RealType>::param_type::param_type(
else
{
__densities_.reserve(__b_.size() - 1);
- for (size_t __i = 0; __i < __b_.size() - 1; ++__i, ++__fW)
- __densities_.push_back(*__fW);
+ for (size_t __i = 0; __i < __b_.size() - 1; ++__i, ++__f_w)
+ __densities_.push_back(*__f_w);
__init();
}
}
diff --git a/libcxx/include/__random/piecewise_linear_distribution.h b/libcxx/include/__random/piecewise_linear_distribution.h
index e69ce9444072..05f00cef06ef 100644
--- a/libcxx/include/__random/piecewise_linear_distribution.h
+++ b/libcxx/include/__random/piecewise_linear_distribution.h
@@ -43,8 +43,8 @@ public:
param_type();
template<class _InputIteratorB, class _InputIteratorW>
- param_type(_InputIteratorB __fB, _InputIteratorB __lB,
- _InputIteratorW __fW);
+ param_type(_InputIteratorB __f_b, _InputIteratorB __l_b,
+ _InputIteratorW __f_w);
#ifndef _LIBCPP_CXX03_LANG
template<class _UnaryOperation>
param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
@@ -94,10 +94,10 @@ public:
piecewise_linear_distribution() {}
template<class _InputIteratorB, class _InputIteratorW>
_LIBCPP_INLINE_VISIBILITY
- piecewise_linear_distribution(_InputIteratorB __fB,
- _InputIteratorB __lB,
- _InputIteratorW __fW)
- : __p_(__fB, __lB, __fW) {}
+ piecewise_linear_distribution(_InputIteratorB __f_b,
+ _InputIteratorB __l_b,
+ _InputIteratorW __f_w)
+ : __p_(__f_b, __l_b, __f_w) {}
#ifndef _LIBCPP_CXX03_LANG
template<class _UnaryOperation>
@@ -219,8 +219,8 @@ piecewise_linear_distribution<_RealType>::param_type::param_type()
template<class _RealType>
template<class _InputIteratorB, class _InputIteratorW>
piecewise_linear_distribution<_RealType>::param_type::param_type(
- _InputIteratorB __fB, _InputIteratorB __lB, _InputIteratorW __fW)
- : __b_(__fB, __lB)
+ _InputIteratorB __f_b, _InputIteratorB __l_b, _InputIteratorW __f_w)
+ : __b_(__f_b, __l_b)
{
if (__b_.size() < 2)
{
@@ -233,8 +233,8 @@ piecewise_linear_distribution<_RealType>::param_type::param_type(
else
{
__densities_.reserve(__b_.size());
- for (size_t __i = 0; __i < __b_.size(); ++__i, ++__fW)
- __densities_.push_back(*__fW);
+ for (size_t __i = 0; __i < __b_.size(); ++__i, ++__f_w)
+ __densities_.push_back(*__f_w);
__init();
}
}
diff --git a/libcxx/include/__ranges/zip_view.h b/libcxx/include/__ranges/zip_view.h
index 560452aa7c69..a8035bc79e12 100644
--- a/libcxx/include/__ranges/zip_view.h
+++ b/libcxx/include/__ranges/zip_view.h
@@ -488,10 +488,10 @@ struct __fn {
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()() const noexcept { return empty_view<tuple<>>{}; }
template <class... _Ranges>
- _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ranges&&... rs) const
- noexcept(noexcept(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(rs)...)))
- -> decltype(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(rs)...)) {
- return zip_view<all_t<_Ranges>...>(std::forward<_Ranges>(rs)...);
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ranges&&... __rs) const
+ noexcept(noexcept(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(__rs)...)))
+ -> decltype(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(__rs)...)) {
+ return zip_view<all_t<_Ranges>...>(std::forward<_Ranges>(__rs)...);
}
};
diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer
index e484e70440c9..7409b51b1f96 100644
--- a/libcxx/include/__split_buffer
+++ b/libcxx/include/__split_buffer
@@ -118,19 +118,10 @@ public:
void __construct_at_end(size_type __n);
void __construct_at_end(size_type __n, const_reference __x);
template <class _InputIter>
- typename enable_if
- <
- __is_cpp17_input_iterator<_InputIter>::value &&
- !__is_cpp17_forward_iterator<_InputIter>::value,
- void
- >::type
+ __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value>
__construct_at_end(_InputIter __first, _InputIter __last);
template <class _ForwardIterator>
- typename enable_if
- <
- __is_cpp17_forward_iterator<_ForwardIterator>::value,
- void
- >::type
+ __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value>
__construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
_LIBCPP_INLINE_VISIBILITY void __destruct_at_begin(pointer __new_begin)
@@ -239,12 +230,7 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_referen
template <class _Tp, class _Allocator>
template <class _InputIter>
-typename enable_if
-<
- __is_cpp17_input_iterator<_InputIter>::value &&
- !__is_cpp17_forward_iterator<_InputIter>::value,
- void
->::type
+__enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value>
__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last)
{
__alloc_rr& __a = this->__alloc();
@@ -267,11 +253,7 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIt
template <class _Tp, class _Allocator>
template <class _ForwardIterator>
-typename enable_if
-<
- __is_cpp17_forward_iterator<_ForwardIterator>::value,
- void
->::type
+__enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value>
__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
{
_ConstructTransaction __tx(&this->__end_, _VSTD::distance(__first, __last));
diff --git a/libcxx/include/__string/char_traits.h b/libcxx/include/__string/char_traits.h
index 457a771b94cf..18ad67b28e16 100644
--- a/libcxx/include/__string/char_traits.h
+++ b/libcxx/include/__string/char_traits.h
@@ -802,9 +802,7 @@ __str_rfind(const _CharT *__p, _SizeT __sz,
__pos += __n;
else
__pos = __sz;
- const _CharT* __r = _VSTD::__find_end(
- __p, __p + __pos, __s, __s + __n, _Traits::eq,
- random_access_iterator_tag(), random_access_iterator_tag());
+ const _CharT* __r = std::__find_end_classic(__p, __p + __pos, __s, __s + __n, _Traits::eq);
if (__n > 0 && __r == __p + __pos)
return __npos;
return static_cast<_SizeT>(__r - __p);
diff --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support
index 8f1efb7854b7..a7f0da972a8d 100644
--- a/libcxx/include/__threading_support
+++ b/libcxx/include/__threading_support
@@ -201,15 +201,15 @@ int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
// Execute once
_LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
- void (*init_routine)());
+int __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
+ void (*__init_routine)());
// Thread id
_LIBCPP_THREAD_ABI_VISIBILITY
-bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
+bool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
_LIBCPP_THREAD_ABI_VISIBILITY
-bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
+bool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
// Thread
_LIBCPP_THREAD_ABI_VISIBILITY
@@ -347,22 +347,22 @@ int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
}
// Execute once
-int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
- void (*init_routine)()) {
- return pthread_once(flag, init_routine);
+int __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
+ void (*__init_routine)()) {
+ return pthread_once(__flag, __init_routine);
}
// Thread id
// Returns non-zero if the thread ids are equal, otherwise 0
-bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
+bool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2)
{
- return t1 == t2;
+ return __t1 == __t2;
}
// Returns non-zero if t1 < t2, otherwise 0
-bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
+bool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2)
{
- return t1 < t2;
+ return __t1 < __t2;
}
// Thread
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index e5dd1f4d45ea..8d8449706871 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -597,8 +597,7 @@ struct __tree_key_value_types<__value_type<_Key, _Tp> > {
template <class _Up>
_LIBCPP_INLINE_VISIBILITY
- static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
- key_type const&>::type
+ static __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, key_type const&>
__get_key(_Up& __t) {
return __t.first;
}
@@ -611,8 +610,7 @@ struct __tree_key_value_types<__value_type<_Key, _Tp> > {
template <class _Up>
_LIBCPP_INLINE_VISIBILITY
- static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
- __container_value_type const&>::type
+ static __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, __container_value_type const&>
__get_value(_Up& __t) {
return __t;
}
@@ -1175,10 +1173,8 @@ public:
template <class _First, class _Second>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<
- __can_extract_map_key<_First, key_type, __container_value_type>::value,
- pair<iterator, bool>
- >::type __emplace_unique(_First&& __f, _Second&& __s) {
+ __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, pair<iterator, bool> >
+ __emplace_unique(_First&& __f, _Second&& __s) {
return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
_VSTD::forward<_Second>(__s));
}
@@ -1219,10 +1215,8 @@ public:
template <class _First, class _Second>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<
- __can_extract_map_key<_First, key_type, __container_value_type>::value,
- iterator
- >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) {
+ __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, iterator>
+ __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) {
return __emplace_hint_unique_key_args(__p, __f,
_VSTD::forward<_First>(__f),
_VSTD::forward<_Second>(__s)).first;
@@ -1275,21 +1269,15 @@ public:
return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v)).first;
}
- template <class _Vp, class = typename enable_if<
- !is_same<typename __unconstref<_Vp>::type,
- __container_value_type
- >::value
- >::type>
+ template <class _Vp,
+ class = __enable_if_t<!is_same<typename __unconstref<_Vp>::type, __container_value_type>::value> >
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> __insert_unique(_Vp&& __v) {
return __emplace_unique(_VSTD::forward<_Vp>(__v));
}
- template <class _Vp, class = typename enable_if<
- !is_same<typename __unconstref<_Vp>::type,
- __container_value_type
- >::value
- >::type>
+ template <class _Vp,
+ class = __enable_if_t<!is_same<typename __unconstref<_Vp>::type, __container_value_type>::value> >
_LIBCPP_INLINE_VISIBILITY
iterator __insert_unique(const_iterator __p, _Vp&& __v) {
return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v));
diff --git a/libcxx/include/__tuple b/libcxx/include/__tuple
index 6d13bb24c579..f85036e7af1d 100644
--- a/libcxx/include/__tuple
+++ b/libcxx/include/__tuple
@@ -30,14 +30,14 @@ using __enable_if_tuple_size_imp = _Tp;
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
const _Tp,
- typename enable_if<!is_volatile<_Tp>::value>::type,
+ __enable_if_t<!is_volatile<_Tp>::value>,
integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
: public integral_constant<size_t, tuple_size<_Tp>::value> {};
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
volatile _Tp,
- typename enable_if<!is_const<_Tp>::value>::type,
+ __enable_if_t<!is_const<_Tp>::value>,
integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
: public integral_constant<size_t, tuple_size<_Tp>::value> {};
@@ -393,7 +393,7 @@ struct __tuple_sfinae_base {
template <template <class, class...> class _Trait,
class ..._LArgs, class ..._RArgs>
static auto __do_test(__tuple_types<_LArgs...>, __tuple_types<_RArgs...>)
- -> __all<typename enable_if<_Trait<_LArgs, _RArgs>::value, bool>::type{true}...>;
+ -> __all<__enable_if_t<_Trait<_LArgs, _RArgs>::value, bool>{true}...>;
template <template <class...> class>
static auto __do_test(...) -> false_type;
diff --git a/libcxx/include/__type_traits/extent.h b/libcxx/include/__type_traits/extent.h
index 935ec4937c0a..0a4d84e05e23 100644
--- a/libcxx/include/__type_traits/extent.h
+++ b/libcxx/include/__type_traits/extent.h
@@ -19,7 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__array_extent)
+#if __has_builtin(__array_extent)
template<class _Tp, size_t _Dim = 0>
struct _LIBCPP_TEMPLATE_VIS extent
@@ -30,7 +30,7 @@ template <class _Tp, unsigned _Ip = 0>
inline constexpr size_t extent_v = __array_extent(_Tp, _Ip);
#endif
-#else // __has_keyword(__array_extent)
+#else // __has_builtin(__array_extent)
template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TEMPLATE_VIS extent
: public integral_constant<size_t, 0> {};
@@ -48,7 +48,7 @@ template <class _Tp, unsigned _Ip = 0>
inline constexpr size_t extent_v = extent<_Tp, _Ip>::value;
#endif
-#endif // __has_keyword(__array_extent)
+#endif // __has_builtin(__array_extent)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/has_virtual_destructor.h b/libcxx/include/__type_traits/has_virtual_destructor.h
index 33574373632e..1f0bd188b717 100644
--- a/libcxx/include/__type_traits/has_virtual_destructor.h
+++ b/libcxx/include/__type_traits/has_virtual_destructor.h
@@ -18,7 +18,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_feature(has_virtual_destructor) || defined(_LIBCPP_COMPILER_GCC)
+#if __has_builtin(__has_virtual_destructor)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_virtual_destructor
: public integral_constant<bool, __has_virtual_destructor(_Tp)> {};
diff --git a/libcxx/include/__type_traits/is_array.h b/libcxx/include/__type_traits/is_array.h
index 766d2a203028..bc105908982c 100644
--- a/libcxx/include/__type_traits/is_array.h
+++ b/libcxx/include/__type_traits/is_array.h
@@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// TODO: Clang incorrectly reports that __is_array is true for T[0].
// Re-enable the branch once https://llvm.org/PR54705 is fixed.
-#if __has_keyword(__is_array) && 0
+#if __has_builtin(__is_array) && 0
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_array : _BoolConstant<__is_array(_Tp)> { };
@@ -45,7 +45,7 @@ template <class _Tp>
inline constexpr bool is_array_v = is_array<_Tp>::value;
#endif
-#endif // __has_keyword(__is_array)
+#endif // __has_builtin(__is_array)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_assignable.h b/libcxx/include/__type_traits/is_assignable.h
index edc864cae065..b8cb6df9df4a 100644
--- a/libcxx/include/__type_traits/is_assignable.h
+++ b/libcxx/include/__type_traits/is_assignable.h
@@ -20,7 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template<typename, typename _Tp> struct __select_2nd { typedef _LIBCPP_NODEBUG _Tp type; };
-#if __has_keyword(__is_assignable)
+#if __has_builtin(__is_assignable)
template<class _Tp, class _Up>
struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> { };
@@ -30,7 +30,7 @@ template <class _Tp, class _Arg>
inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Arg);
#endif
-#else // __has_keyword(__is_assignable)
+#else // __has_builtin(__is_assignable)
template <class _Tp, class _Arg>
typename __select_2nd<decltype((declval<_Tp>() = declval<_Arg>())), true_type>::type
@@ -59,7 +59,7 @@ template <class _Tp, class _Arg>
inline constexpr bool is_assignable_v = is_assignable<_Tp, _Arg>::value;
#endif
-#endif // __has_keyword(__is_assignable)
+#endif // __has_builtin(__is_assignable)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_compound.h b/libcxx/include/__type_traits/is_compound.h
index 643edd78229a..1395ed8d417f 100644
--- a/libcxx/include/__type_traits/is_compound.h
+++ b/libcxx/include/__type_traits/is_compound.h
@@ -19,7 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_compound)
+#if __has_builtin(__is_compound)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> { };
@@ -29,7 +29,7 @@ template <class _Tp>
inline constexpr bool is_compound_v = __is_compound(_Tp);
#endif
-#else // __has_keyword(__is_compound)
+#else // __has_builtin(__is_compound)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_compound
: public integral_constant<bool, !is_fundamental<_Tp>::value> {};
@@ -39,7 +39,7 @@ template <class _Tp>
inline constexpr bool is_compound_v = is_compound<_Tp>::value;
#endif
-#endif // __has_keyword(__is_compound)
+#endif // __has_builtin(__is_compound)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_const.h b/libcxx/include/__type_traits/is_const.h
index 5501832f560b..42b892c58d50 100644
--- a/libcxx/include/__type_traits/is_const.h
+++ b/libcxx/include/__type_traits/is_const.h
@@ -18,7 +18,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_const)
+#if __has_builtin(__is_const)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> { };
@@ -38,7 +38,7 @@ template <class _Tp>
inline constexpr bool is_const_v = is_const<_Tp>::value;
#endif
-#endif // __has_keyword(__is_const)
+#endif // __has_builtin(__is_const)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_convertible.h b/libcxx/include/__type_traits/is_convertible.h
index 884e808e2ae4..7e49cd4e6a31 100644
--- a/libcxx/include/__type_traits/is_convertible.h
+++ b/libcxx/include/__type_traits/is_convertible.h
@@ -24,12 +24,12 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_feature(is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
+#if __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS is_convertible
: public integral_constant<bool, __is_convertible_to(_T1, _T2)> {};
-#else // __has_feature(is_convertible_to)
+#else // __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
namespace __is_convertible_imp
{
@@ -96,7 +96,7 @@ template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS is_convertible
static const size_t __complete_check2 = __is_convertible_check<_T2>::__v;
};
-#endif // __has_feature(is_convertible_to)
+#endif // __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
#if _LIBCPP_STD_VER > 14
template <class _From, class _To>
diff --git a/libcxx/include/__type_traits/is_destructible.h b/libcxx/include/__type_traits/is_destructible.h
index 489451007873..5e9ac5579fdd 100644
--- a/libcxx/include/__type_traits/is_destructible.h
+++ b/libcxx/include/__type_traits/is_destructible.h
@@ -22,7 +22,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_destructible)
+#if __has_builtin(__is_destructible)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> { };
@@ -32,7 +32,7 @@ template <class _Tp>
inline constexpr bool is_destructible_v = __is_destructible(_Tp);
#endif
-#else // __has_keyword(__is_destructible)
+#else // __has_builtin(__is_destructible)
// if it's a reference, return true
// if it's a function, return false
@@ -95,7 +95,7 @@ template <class _Tp>
inline constexpr bool is_destructible_v = is_destructible<_Tp>::value;
#endif
-#endif // __has_keyword(__is_destructible)
+#endif // __has_builtin(__is_destructible)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_function.h b/libcxx/include/__type_traits/is_function.h
index bce980c21b4e..53f34b39eb9a 100644
--- a/libcxx/include/__type_traits/is_function.h
+++ b/libcxx/include/__type_traits/is_function.h
@@ -20,7 +20,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_function)
+#if __has_builtin(__is_function)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_function : integral_constant<bool, __is_function(_Tp)> {};
@@ -31,7 +31,7 @@ template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_function
: public integral_constant<bool, !(is_reference<_Tp>::value || is_const<const _Tp>::value)> {};
-#endif // __has_keyword(__is_function)
+#endif // __has_builtin(__is_function)
#if _LIBCPP_STD_VER > 14
template <class _Tp>
diff --git a/libcxx/include/__type_traits/is_fundamental.h b/libcxx/include/__type_traits/is_fundamental.h
index aaa7063eef9b..46f81a103583 100644
--- a/libcxx/include/__type_traits/is_fundamental.h
+++ b/libcxx/include/__type_traits/is_fundamental.h
@@ -20,7 +20,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_fundamental)
+#if __has_builtin(__is_fundamental)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> { };
@@ -30,7 +30,7 @@ template <class _Tp>
inline constexpr bool is_fundamental_v = __is_fundamental(_Tp);
#endif
-#else // __has_keyword(__is_fundamental)
+#else // __has_builtin(__is_fundamental)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_fundamental
: public integral_constant<bool, is_void<_Tp>::value ||
@@ -42,7 +42,7 @@ template <class _Tp>
inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
#endif
-#endif // __has_keyword(__is_fundamental)
+#endif // __has_builtin(__is_fundamental)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_integral.h b/libcxx/include/__type_traits/is_integral.h
index 09378735d94e..c1c573a75e0a 100644
--- a/libcxx/include/__type_traits/is_integral.h
+++ b/libcxx/include/__type_traits/is_integral.h
@@ -45,7 +45,7 @@ template <> struct __libcpp_is_integral<__int128_t> { enum { va
template <> struct __libcpp_is_integral<__uint128_t> { enum { value = 1 }; };
#endif
-#if __has_keyword(__is_integral)
+#if __has_builtin(__is_integral)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_integral : _BoolConstant<__is_integral(_Tp)> { };
@@ -65,7 +65,7 @@ template <class _Tp>
inline constexpr bool is_integral_v = is_integral<_Tp>::value;
#endif
-#endif // __has_keyword(__is_integral)
+#endif // __has_builtin(__is_integral)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_member_function_pointer.h b/libcxx/include/__type_traits/is_member_function_pointer.h
index f18f3ebc5a3a..2d2ff81e091a 100644
--- a/libcxx/include/__type_traits/is_member_function_pointer.h
+++ b/libcxx/include/__type_traits/is_member_function_pointer.h
@@ -36,7 +36,7 @@ template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> {
};
};
-#if __has_keyword(__is_member_function_pointer)
+#if __has_builtin(__is_member_function_pointer)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
@@ -47,7 +47,7 @@ template <class _Tp>
inline constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Tp);
#endif
-#else // __has_keyword(__is_member_function_pointer)
+#else // __has_builtin(__is_member_function_pointer)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
: public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_func > {};
@@ -57,7 +57,7 @@ template <class _Tp>
inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value;
#endif
-#endif // __has_keyword(__is_member_function_pointer)
+#endif // __has_builtin(__is_member_function_pointer)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_member_object_pointer.h b/libcxx/include/__type_traits/is_member_object_pointer.h
index 41f81d529388..250a22c97440 100644
--- a/libcxx/include/__type_traits/is_member_object_pointer.h
+++ b/libcxx/include/__type_traits/is_member_object_pointer.h
@@ -18,7 +18,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_member_object_pointer)
+#if __has_builtin(__is_member_object_pointer)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
@@ -29,7 +29,7 @@ template <class _Tp>
inline constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Tp);
#endif
-#else // __has_keyword(__is_member_object_pointer)
+#else // __has_builtin(__is_member_object_pointer)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
: public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_obj > {};
@@ -39,7 +39,7 @@ template <class _Tp>
inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value;
#endif
-#endif // __has_keyword(__is_member_object_pointer)
+#endif // __has_builtin(__is_member_object_pointer)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_member_pointer.h b/libcxx/include/__type_traits/is_member_pointer.h
index 76595dfdab7f..448bcc23d55e 100644
--- a/libcxx/include/__type_traits/is_member_pointer.h
+++ b/libcxx/include/__type_traits/is_member_pointer.h
@@ -18,7 +18,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_member_pointer)
+#if __has_builtin(__is_member_pointer)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> { };
@@ -28,7 +28,7 @@ template <class _Tp>
inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
#endif
-#else // __has_keyword(__is_member_pointer)
+#else // __has_builtin(__is_member_pointer)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_pointer
: public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_member > {};
@@ -38,7 +38,7 @@ template <class _Tp>
inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
#endif
-#endif // __has_keyword(__is_member_pointer)
+#endif // __has_builtin(__is_member_pointer)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_nothrow_assignable.h b/libcxx/include/__type_traits/is_nothrow_assignable.h
index 18e0e70a561d..e3ce33ece895 100644
--- a/libcxx/include/__type_traits/is_nothrow_assignable.h
+++ b/libcxx/include/__type_traits/is_nothrow_assignable.h
@@ -19,7 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_nothrow_assignable)
+#if __has_builtin(__is_nothrow_assignable)
template <class _Tp, class _Arg>
struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable
@@ -47,7 +47,7 @@ struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable
{
};
-#endif // _LIBCPP_HAS_NO_NOEXCEPT
+#endif // __has_builtin(__is_nothrow_assignable)
#if _LIBCPP_STD_VER > 14
template <class _Tp, class _Arg>
diff --git a/libcxx/include/__type_traits/is_nothrow_constructible.h b/libcxx/include/__type_traits/is_nothrow_constructible.h
index 1f25d61baa63..92d6e8343e03 100644
--- a/libcxx/include/__type_traits/is_nothrow_constructible.h
+++ b/libcxx/include/__type_traits/is_nothrow_constructible.h
@@ -19,7 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_nothrow_constructible)
+#if __has_builtin(__is_nothrow_constructible)
template <class _Tp, class... _Args>
struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible
@@ -62,7 +62,7 @@ struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp[_Ns]>
{
};
-#endif // _LIBCPP_HAS_NO_NOEXCEPT
+#endif // __has_builtin(__is_nothrow_constructible)
#if _LIBCPP_STD_VER > 14
diff --git a/libcxx/include/__type_traits/is_object.h b/libcxx/include/__type_traits/is_object.h
index 0d8339d19492..943f1a736cd5 100644
--- a/libcxx/include/__type_traits/is_object.h
+++ b/libcxx/include/__type_traits/is_object.h
@@ -22,7 +22,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_object)
+#if __has_builtin(__is_object)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> { };
@@ -32,7 +32,7 @@ template <class _Tp>
inline constexpr bool is_object_v = __is_object(_Tp);
#endif
-#else // __has_keyword(__is_object)
+#else // __has_builtin(__is_object)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_object
: public integral_constant<bool, is_scalar<_Tp>::value ||
@@ -45,7 +45,7 @@ template <class _Tp>
inline constexpr bool is_object_v = is_object<_Tp>::value;
#endif
-#endif // __has_keyword(__is_object)
+#endif // __has_builtin(__is_object)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_pod.h b/libcxx/include/__type_traits/is_pod.h
index 4317182f8964..497060e00557 100644
--- a/libcxx/include/__type_traits/is_pod.h
+++ b/libcxx/include/__type_traits/is_pod.h
@@ -18,7 +18,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_feature(is_pod) || defined(_LIBCPP_COMPILER_GCC)
+#if __has_builtin(__is_pod)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pod
: public integral_constant<bool, __is_pod(_Tp)> {};
@@ -31,7 +31,7 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pod
is_trivially_copy_assignable<_Tp>::value &&
is_trivially_destructible<_Tp>::value> {};
-#endif
+#endif // __has_builtin(__is_pod)
#if _LIBCPP_STD_VER > 14
template <class _Tp>
diff --git a/libcxx/include/__type_traits/is_pointer.h b/libcxx/include/__type_traits/is_pointer.h
index 2139b03282e7..63c82ae4715c 100644
--- a/libcxx/include/__type_traits/is_pointer.h
+++ b/libcxx/include/__type_traits/is_pointer.h
@@ -19,7 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_pointer)
+#if __has_builtin(__is_pointer)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { };
@@ -29,7 +29,7 @@ template <class _Tp>
inline constexpr bool is_pointer_v = __is_pointer(_Tp);
#endif
-#else // __has_keyword(__is_pointer)
+#else // __has_builtin(__is_pointer)
template <class _Tp> struct __libcpp_is_pointer : public false_type {};
template <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {};
@@ -50,7 +50,7 @@ template <class _Tp>
inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
#endif
-#endif // __has_keyword(__is_pointer)
+#endif // __has_builtin(__is_pointer)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_reference.h b/libcxx/include/__type_traits/is_reference.h
index 8aa55c13ff83..27ca2ddb5a72 100644
--- a/libcxx/include/__type_traits/is_reference.h
+++ b/libcxx/include/__type_traits/is_reference.h
@@ -18,9 +18,9 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_lvalue_reference) && \
- __has_keyword(__is_rvalue_reference) && \
- __has_keyword(__is_reference)
+#if __has_builtin(__is_lvalue_reference) && \
+ __has_builtin(__is_rvalue_reference) && \
+ __has_builtin(__is_reference)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> { };
@@ -40,7 +40,7 @@ template <class _Tp>
inline constexpr bool is_rvalue_reference_v = __is_rvalue_reference(_Tp);
#endif
-#else // __has_keyword(__is_lvalue_reference) && etc...
+#else // __has_builtin(__is_lvalue_reference) && etc...
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {};
@@ -63,7 +63,7 @@ template <class _Tp>
inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value;
#endif
-#endif // __has_keyword(__is_lvalue_reference) && etc...
+#endif // __has_builtin(__is_lvalue_reference) && etc...
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_scalar.h b/libcxx/include/__type_traits/is_scalar.h
index 0ca34c7cf79b..ee856dbbfec7 100644
--- a/libcxx/include/__type_traits/is_scalar.h
+++ b/libcxx/include/__type_traits/is_scalar.h
@@ -22,7 +22,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_scalar)
+#if __has_builtin(__is_scalar)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> { };
@@ -32,7 +32,7 @@ template <class _Tp>
inline constexpr bool is_scalar_v = __is_scalar(_Tp);
#endif
-#else // __has_keyword(__is_scalar)
+#else // __has_builtin(__is_scalar)
template <class _Tp> struct __is_block : false_type {};
#if defined(_LIBCPP_HAS_EXTENSION_BLOCKS)
@@ -54,7 +54,7 @@ template <class _Tp>
inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
#endif
-#endif // __has_keyword(__is_scalar)
+#endif // __has_builtin(__is_scalar)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_signed.h b/libcxx/include/__type_traits/is_signed.h
index 241d6f551a4b..e9722c9b2192 100644
--- a/libcxx/include/__type_traits/is_signed.h
+++ b/libcxx/include/__type_traits/is_signed.h
@@ -18,7 +18,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_signed)
+#if __has_builtin(__is_signed)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> { };
@@ -28,7 +28,7 @@ template <class _Tp>
inline constexpr bool is_signed_v = __is_signed(_Tp);
#endif
-#else // __has_keyword(__is_signed)
+#else // __has_builtin(__is_signed)
template <class _Tp, bool = is_integral<_Tp>::value>
struct __libcpp_is_signed_impl : public _BoolConstant<(_Tp(-1) < _Tp(0))> {};
@@ -48,7 +48,7 @@ template <class _Tp>
inline constexpr bool is_signed_v = is_signed<_Tp>::value;
#endif
-#endif // __has_keyword(__is_signed)
+#endif // __has_builtin(__is_signed)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_standard_layout.h b/libcxx/include/__type_traits/is_standard_layout.h
index 375d08721e90..0d8b5f480f0c 100644
--- a/libcxx/include/__type_traits/is_standard_layout.h
+++ b/libcxx/include/__type_traits/is_standard_layout.h
@@ -19,7 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_standard_layout
-#if __has_feature(is_standard_layout) || defined(_LIBCPP_COMPILER_GCC)
+#if __has_builtin(__is_standard_layout)
: public integral_constant<bool, __is_standard_layout(_Tp)>
#else
: integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value>
diff --git a/libcxx/include/__type_traits/is_trivial.h b/libcxx/include/__type_traits/is_trivial.h
index 011963c3d0e6..73c2093d4082 100644
--- a/libcxx/include/__type_traits/is_trivial.h
+++ b/libcxx/include/__type_traits/is_trivial.h
@@ -19,7 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivial
-#if __has_feature(is_trivial) || defined(_LIBCPP_COMPILER_GCC)
+#if __has_builtin(__is_trivial)
: public integral_constant<bool, __is_trivial(_Tp)>
#else
: integral_constant<bool, is_trivially_copyable<_Tp>::value &&
diff --git a/libcxx/include/__type_traits/is_trivially_destructible.h b/libcxx/include/__type_traits/is_trivially_destructible.h
index 81181cdf841d..3376c3eeff43 100644
--- a/libcxx/include/__type_traits/is_trivially_destructible.h
+++ b/libcxx/include/__type_traits/is_trivially_destructible.h
@@ -18,12 +18,12 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_trivially_destructible)
+#if __has_builtin(__is_trivially_destructible)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
: public integral_constant<bool, __is_trivially_destructible(_Tp)> {};
-#elif __has_feature(has_trivial_destructor) || defined(_LIBCPP_COMPILER_GCC)
+#elif __has_builtin(__has_trivial_destructor)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
: public integral_constant<bool, is_destructible<_Tp>::value && __has_trivial_destructor(_Tp)> {};
@@ -40,7 +40,7 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible<_Tp[]>
: public false_type {};
-#endif
+#endif // __has_builtin(__is_trivially_destructible)
#if _LIBCPP_STD_VER > 14
template <class _Tp>
diff --git a/libcxx/include/__type_traits/is_unsigned.h b/libcxx/include/__type_traits/is_unsigned.h
index bb279fdb729d..17cd909d5478 100644
--- a/libcxx/include/__type_traits/is_unsigned.h
+++ b/libcxx/include/__type_traits/is_unsigned.h
@@ -21,7 +21,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
// Before AppleClang 14, __is_unsigned returned true for enums with signed underlying type.
-#if __has_keyword(__is_unsigned) && !(defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1400)
+#if __has_builtin(__is_unsigned) && !(defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1400)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> { };
@@ -31,7 +31,7 @@ template <class _Tp>
inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
#endif
-#else // __has_keyword(__is_unsigned)
+#else // __has_builtin(__is_unsigned)
template <class _Tp, bool = is_integral<_Tp>::value>
struct __libcpp_is_unsigned_impl : public _BoolConstant<(_Tp(0) < _Tp(-1))> {};
@@ -51,7 +51,7 @@ template <class _Tp>
inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
#endif
-#endif // __has_keyword(__is_unsigned)
+#endif // __has_builtin(__is_unsigned)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_void.h b/libcxx/include/__type_traits/is_void.h
index 29e68cc529df..4cebf18633b2 100644
--- a/libcxx/include/__type_traits/is_void.h
+++ b/libcxx/include/__type_traits/is_void.h
@@ -18,7 +18,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_void)
+#if __has_builtin(__is_void)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> { };
@@ -38,7 +38,7 @@ template <class _Tp>
inline constexpr bool is_void_v = is_void<_Tp>::value;
#endif
-#endif // __has_keyword(__is_void)
+#endif // __has_builtin(__is_void)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_volatile.h b/libcxx/include/__type_traits/is_volatile.h
index 372703e7ced6..fb922679d62b 100644
--- a/libcxx/include/__type_traits/is_volatile.h
+++ b/libcxx/include/__type_traits/is_volatile.h
@@ -18,7 +18,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_keyword(__is_volatile)
+#if __has_builtin(__is_volatile)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> { };
@@ -38,7 +38,7 @@ template <class _Tp>
inline constexpr bool is_volatile_v = is_volatile<_Tp>::value;
#endif
-#endif // __has_keyword(__is_volatile)
+#endif // __has_builtin(__is_volatile)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index 0154dbc39c08..f616a031960e 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -287,6 +287,50 @@ namespace ranges {
indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
constexpr bool ranges::is_partitioned(R&& r, Pred pred, Proj proj = {}); // since C++20
+ template<random_access_iterator I, sentinel_for<I> S, class Comp = ranges::less,
+ class Proj = identity>
+ requires sortable<I, Comp, Proj>
+ constexpr I
+ ranges::push_heap(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<random_access_range R, class Comp = ranges::less, class Proj = identity>
+ requires sortable<iterator_t<R>, Comp, Proj>
+ constexpr borrowed_iterator_t<R>
+ ranges::push_heap(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<random_access_iterator I, sentinel_for<I> S, class Comp = ranges::less,
+ class Proj = identity>
+ requires sortable<I, Comp, Proj>
+ constexpr I
+ ranges::pop_heap(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<random_access_range R, class Comp = ranges::less, class Proj = identity>
+ requires sortable<iterator_t<R>, Comp, Proj>
+ constexpr borrowed_iterator_t<R>
+ ranges::pop_heap(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<random_access_iterator I, sentinel_for<I> S, class Comp = ranges::less,
+ class Proj = identity>
+ requires sortable<I, Comp, Proj>
+ constexpr I
+ ranges::make_heap(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<random_access_range R, class Comp = ranges::less, class Proj = identity>
+ requires sortable<iterator_t<R>, Comp, Proj>
+ constexpr borrowed_iterator_t<R>
+ ranges::make_heap(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<random_access_iterator I, sentinel_for<I> S, class Comp = ranges::less,
+ class Proj = identity>
+ requires sortable<I, Comp, Proj>
+ constexpr I
+ ranges::sort_heap(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<random_access_range R, class Comp = ranges::less, class Proj = identity>
+ requires sortable<iterator_t<R>, Comp, Proj>
+ constexpr borrowed_iterator_t<R>
+ ranges::sort_heap(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+
template<bidirectional_iterator I, sentinel_for<I> S>
requires permutable<I>
constexpr I ranges::reverse(I first, S last); // since C++20
@@ -379,6 +423,17 @@ namespace ranges {
constexpr borrowed_iterator_t<R>
ranges::is_sorted_until(R&& r, Comp comp = {}, Proj proj = {}); // since C++20
+ template<random_access_iterator I, sentinel_for<I> S, class Comp = ranges::less,
+ class Proj = identity>
+ requires sortable<I, Comp, Proj>
+ constexpr I
+ ranges::nth_element(I first, I nth, S last, Comp comp = {}, Proj proj = {}); // since C++20
+
+ template<random_access_range R, class Comp = ranges::less, class Proj = identity>
+ requires sortable<iterator_t<R>, Comp, Proj>
+ constexpr borrowed_iterator_t<R>
+ ranges::nth_element(R&& r, iterator_t<R> nth, Comp comp = {}, Proj proj = {}); // since C++20
+
template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,
indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less>
constexpr I upper_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); // since C++20
@@ -493,7 +548,170 @@ namespace ranges {
constexpr ranges::move_result<borrowed_iterator_t<R>, O>
ranges::move(R&& r, O result); // since C++20
+ template<class I1, class I2, class O>
+ using merge_result = in_in_out_result<I1, I2, O>; // since C++20
+
+ template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
+ weakly_incrementable O, class Comp = ranges::less, class Proj1 = identity,
+ class Proj2 = identity>
+ requires mergeable<I1, I2, O, Comp, Proj1, Proj2>
+ constexpr merge_result<I1, I2, O>
+ merge(I1 first1, S1 last1, I2 first2, S2 last2, O result,
+ Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<input_range R1, input_range R2, weakly_incrementable O, class Comp = ranges::less,
+ class Proj1 = identity, class Proj2 = identity>
+ requires mergeable<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>
+ constexpr merge_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O>
+ merge(R1&& r1, R2&& r2, O result,
+ Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<permutable I, sentinel_for<I> S, class T, class Proj = identity>
+ requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
+ constexpr subrange<I> ranges::remove(I first, S last, const T& value, Proj proj = {}); // since C++20
+
+ template<forward_range R, class T, class Proj = identity>
+ requires permutable<iterator_t<R>> &&
+ indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T*>
+ constexpr borrowed_subrange_t<R>
+ ranges::remove(R&& r, const T& value, Proj proj = {}); // since C++20
+
+ template<permutable I, sentinel_for<I> S, class Proj = identity,
+ indirect_unary_predicate<projected<I, Proj>> Pred>
+ constexpr subrange<I> ranges::remove_if(I first, S last, Pred pred, Proj proj = {}); // since C++20
+
+ template<forward_range R, class Proj = identity,
+ indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+ requires permutable<iterator_t<R>>
+ constexpr borrowed_subrange_t<R>
+ ranges::remove_if(R&& r, Pred pred, Proj proj = {}); // since C++20
+
+ template<class I, class O>
+ using set_difference_result = in_out_result<I, O>; // since C++20
+ template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
+ weakly_incrementable O, class Comp = ranges::less,
+ class Proj1 = identity, class Proj2 = identity>
+ requires mergeable<I1, I2, O, Comp, Proj1, Proj2>
+ constexpr set_difference_result<I1, O>
+ set_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result,
+ Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<input_range R1, input_range R2, weakly_incrementable O,
+ class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity>
+ requires mergeable<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>
+ constexpr set_difference_result<borrowed_iterator_t<R1>, O>
+ set_difference(R1&& r1, R2&& r2, O result,
+ Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<class I1, class I2, class O>
+ using set_intersection_result = in_in_out_result<I1, I2, O>; // since C++20
+
+ template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
+ weakly_incrementable O, class Comp = ranges::less,
+ class Proj1 = identity, class Proj2 = identity>
+ requires mergeable<I1, I2, O, Comp, Proj1, Proj2>
+ constexpr set_intersection_result<I1, I2, O>
+ set_intersection(I1 first1, S1 last1, I2 first2, S2 last2, O result,
+ Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
+ weakly_incrementable O, class Comp = ranges::less,
+ class Proj1 = identity, class Proj2 = identity>
+ requires mergeable<I1, I2, O, Comp, Proj1, Proj2>
+ constexpr set_intersection_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O>
+ set_intersection(R1&& r1, R2&& r2, O result,
+ Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template <class _InIter, class _OutIter>
+ using reverse_copy_result = in_out_result<_InIter, _OutIter>; // since C++20
+
+ template<bidirectional_iterator I, sentinel_for<I> S, weakly_incrementable O>
+ requires indirectly_copyable<I, O>
+ constexpr ranges::reverse_copy_result<I, O>
+ ranges::reverse_copy(I first, S last, O result); // since C++20
+
+ template<bidirectional_range R, weakly_incrementable O>
+ requires indirectly_copyable<iterator_t<R>, O>
+ constexpr ranges::reverse_copy_result<borrowed_iterator_t<R>, O>
+ ranges::reverse_copy(R&& r, O result); // since C++20
+
+ template <class _InIter, class _OutIter>
+ using rotate_copy_result = in_out_result<_InIter, _OutIter>; // since C++20
+
+ template<forward_iterator I, sentinel_for<I> S, weakly_incrementable O>
+ requires indirectly_copyable<I, O>
+ constexpr ranges::rotate_copy_result<I, O>
+ ranges::rotate_copy(I first, I middle, S last, O result); // since C++20
+
+ template<forward_range R, weakly_incrementable O>
+ requires indirectly_copyable<iterator_t<R>, O>
+ constexpr ranges::rotate_copy_result<borrowed_iterator_t<R>, O>
+ ranges::rotate_copy(R&& r, iterator_t<R> middle, O result); // since C++20
+
+ template<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2,
+ sentinel_for<I2> S2, class Pred = ranges::equal_to,
+ class Proj1 = identity, class Proj2 = identity>
+ requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
+ constexpr subrange<I1>
+ ranges::search(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
+ Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<forward_range R1, forward_range R2, class Pred = ranges::equal_to,
+ class Proj1 = identity, class Proj2 = identity>
+ requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
+ constexpr borrowed_subrange_t<R1>
+ ranges::search(R1&& r1, R2&& r2, Pred pred = {},
+ Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<forward_iterator I, sentinel_for<I> S, class T,
+ class Pred = ranges::equal_to, class Proj = identity>
+ requires indirectly_comparable<I, const T*, Pred, Proj>
+ constexpr subrange<I>
+ ranges::search_n(I first, S last, iter_difference_t<I> count,
+ const T& value, Pred pred = {}, Proj proj = {}); // since C++20
+
+ template<forward_range R, class T, class Pred = ranges::equal_to,
+ class Proj = identity>
+ requires indirectly_comparable<iterator_t<R>, const T*, Pred, Proj>
+ constexpr borrowed_subrange_t<R>
+ ranges::search_n(R&& r, range_difference_t<R> count,
+ const T& value, Pred pred = {}, Proj proj = {}); // since C++20
+
+ template<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2, sentinel_for<I2> S2,
+ class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
+ requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
+ constexpr subrange<I1>
+ ranges::find_end(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
+ Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<forward_range R1, forward_range R2,
+ class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
+ requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
+ constexpr borrowed_subrange_t<R1>
+ ranges::find_end(R1&& r1, R2&& r2, Pred pred = {},
+ Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
+ template<class I1, class I2, class O>
+ using set_symmetric_difference_result = in_in_out_result<I1, I2, O>; // since C++20
+
+ template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
+ weakly_incrementable O, class Comp = ranges::less,
+ class Proj1 = identity, class Proj2 = identity>
+ requires mergeable<I1, I2, O, Comp, Proj1, Proj2>
+ constexpr set_symmetric_difference_result<I1, I2, O>
+ set_symmetric_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result,
+ Comp comp = {}, Proj1 proj1 = {},
+ Proj2 proj2 = {}); // since C++20
+
+ template<input_range R1, input_range R2, weakly_incrementable O,
+ class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity>
+ requires mergeable<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>
+ constexpr set_symmetric_difference_result<borrowed_iterator_t<R1>,
+ borrowed_iterator_t<R2>, O>
+ set_symmetric_difference(R1&& r1, R2&& r2, O result, Comp comp = {},
+ Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20
+
}
constexpr bool // constexpr in C++20
@@ -1237,6 +1455,7 @@ template <class BidirectionalIterator, class Compare>
#include <__algorithm/ranges_fill.h>
#include <__algorithm/ranges_fill_n.h>
#include <__algorithm/ranges_find.h>
+#include <__algorithm/ranges_find_end.h>
#include <__algorithm/ranges_find_first_of.h>
#include <__algorithm/ranges_find_if.h>
#include <__algorithm/ranges_find_if_not.h>
@@ -1247,8 +1466,10 @@ template <class BidirectionalIterator, class Compare>
#include <__algorithm/ranges_is_sorted_until.h>
#include <__algorithm/ranges_lexicographical_compare.h>
#include <__algorithm/ranges_lower_bound.h>
+#include <__algorithm/ranges_make_heap.h>
#include <__algorithm/ranges_max.h>
#include <__algorithm/ranges_max_element.h>
+#include <__algorithm/ranges_merge.h>
#include <__algorithm/ranges_min.h>
#include <__algorithm/ranges_min_element.h>
#include <__algorithm/ranges_minmax.h>
@@ -1257,10 +1478,23 @@ template <class BidirectionalIterator, class Compare>
#include <__algorithm/ranges_move.h>
#include <__algorithm/ranges_move_backward.h>
#include <__algorithm/ranges_none_of.h>
+#include <__algorithm/ranges_nth_element.h>
+#include <__algorithm/ranges_pop_heap.h>
+#include <__algorithm/ranges_push_heap.h>
+#include <__algorithm/ranges_remove.h>
+#include <__algorithm/ranges_remove_if.h>
#include <__algorithm/ranges_replace.h>
#include <__algorithm/ranges_replace_if.h>
#include <__algorithm/ranges_reverse.h>
+#include <__algorithm/ranges_reverse_copy.h>
+#include <__algorithm/ranges_rotate_copy.h>
+#include <__algorithm/ranges_search.h>
+#include <__algorithm/ranges_search_n.h>
+#include <__algorithm/ranges_set_difference.h>
+#include <__algorithm/ranges_set_intersection.h>
+#include <__algorithm/ranges_set_symmetric_difference.h>
#include <__algorithm/ranges_sort.h>
+#include <__algorithm/ranges_sort_heap.h>
#include <__algorithm/ranges_stable_sort.h>
#include <__algorithm/ranges_swap_ranges.h>
#include <__algorithm/ranges_transform.h>
diff --git a/libcxx/include/any b/libcxx/include/any
index 7e12034b45a7..66f7488e5441 100644
--- a/libcxx/include/any
+++ b/libcxx/include/any
@@ -271,7 +271,7 @@ public:
is_copy_constructible<_Tp>::value>
>
_LIBCPP_INLINE_VISIBILITY
- _Tp& emplace(_Args&&... args);
+ _Tp& emplace(_Args&&...);
template <class _ValueType, class _Up, class ..._Args,
class _Tp = decay_t<_ValueType>,
diff --git a/libcxx/include/array b/libcxx/include/array
index e96c3d813339..867dd6b1bcc6 100644
--- a/libcxx/include/array
+++ b/libcxx/include/array
@@ -438,12 +438,7 @@ operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-typename enable_if
-<
- _Size == 0 ||
- __is_swappable<_Tp>::value,
- void
->::type
+__enable_if_t<_Size == 0 || __is_swappable<_Tp>::value, void>
swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y)
_NOEXCEPT_(noexcept(__x.swap(__y)))
{
diff --git a/libcxx/include/atomic b/libcxx/include/atomic
index 0c6d3079c96a..92da4820e928 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -906,8 +906,8 @@ struct __cxx_atomic_base_impl {
#else
__cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
#endif // _LIBCPP_CXX03_LANG
- _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
- : __a_value(value) {}
+ _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT
+ : __a_value(__value) {}
_LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
};
@@ -1451,8 +1451,8 @@ struct __cxx_atomic_impl : public _Base {
"std::atomic<T> requires that 'T' be a trivially copyable type");
_LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT = default;
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
- : _Base(value) {}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT
+ : _Base(__value) {}
};
#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
@@ -2696,7 +2696,6 @@ typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400
-# pragma clang deprecated(ATOMIC_FLAG_INIT)
# pragma clang deprecated(ATOMIC_VAR_INIT)
# endif
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
diff --git a/libcxx/include/barrier b/libcxx/include/barrier
index 9d91d255df9a..00518035283f 100644
--- a/libcxx/include/barrier
+++ b/libcxx/include/barrier
@@ -130,10 +130,10 @@ public:
{
}
[[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- arrival_token arrive(ptrdiff_t update)
+ arrival_token arrive(ptrdiff_t __update)
{
auto const __old_phase = __phase_.load(memory_order_relaxed);
- for(; update; --update)
+ for(; __update; --__update)
if(__arrive_barrier_algorithm_base(__base_.get(), __old_phase)) {
__completion_();
__expected_ += __expected_adjustment_.load(memory_order_relaxed);
@@ -300,9 +300,9 @@ public:
barrier& operator=(barrier const&) = delete;
[[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
- arrival_token arrive(ptrdiff_t update = 1)
+ arrival_token arrive(ptrdiff_t __update = 1)
{
- return __b.arrive(update);
+ return __b.arrive(__update);
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void wait(arrival_token&& __phase) const
diff --git a/libcxx/include/charconv b/libcxx/include/charconv
index 6a63e5fe9057..9f474ae711f3 100644
--- a/libcxx/include/charconv
+++ b/libcxx/include/charconv
@@ -117,32 +117,22 @@ from_chars_result from_chars(const char*, const char*, bool, int = 10) = delete;
namespace __itoa
{
-
template <typename _Tp, typename = void>
-struct _LIBCPP_HIDDEN __traits_base
-{
- using type = uint64_t;
-
- static _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v)
- {
- auto __t = (64 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
- return __t - (__v < __table<>::__pow10_64[__t]) + 1;
- }
-
- static _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v)
- {
- return __itoa::__base_10_u64(__p, __v);
- }
-
- static _LIBCPP_HIDE_FROM_ABI decltype(__table<>::__pow10_64)& __pow() { return __table<>::__pow10_64; }
-};
+struct _LIBCPP_HIDDEN __traits_base;
template <typename _Tp>
-struct _LIBCPP_HIDDEN
- __traits_base<_Tp, decltype(void(uint32_t{declval<_Tp>()}))>
+struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) <= sizeof(uint32_t)>>
{
using type = uint32_t;
+ /// The width estimation using a log10 algorithm.
+ ///
+ /// The algorithm is based on
+ /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+ /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
+ /// function requires its input to have at least one bit set the value of
+ /// zero is set to one. This means the first element of the lookup table is
+ /// zero.
static _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v)
{
auto __t = (32 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
@@ -158,6 +148,61 @@ struct _LIBCPP_HIDDEN
};
template <typename _Tp>
+struct _LIBCPP_HIDDEN
+ __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(uint64_t)>> {
+ using type = uint64_t;
+
+ /// The width estimation using a log10 algorithm.
+ ///
+ /// The algorithm is based on
+ /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+ /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
+ /// function requires its input to have at least one bit set the value of
+ /// zero is set to one. This means the first element of the lookup table is
+ /// zero.
+ static _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
+ auto __t = (64 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
+ return __t - (__v < __table<>::__pow10_64[__t]) + 1;
+ }
+
+ static _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { return __itoa::__base_10_u64(__p, __v); }
+
+ static _LIBCPP_HIDE_FROM_ABI decltype(__table<>::__pow10_64)& __pow() { return __table<>::__pow10_64; }
+};
+
+
+# ifndef _LIBCPP_HAS_NO_INT128
+template <typename _Tp>
+struct _LIBCPP_HIDDEN
+ __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__uint128_t)> > {
+ using type = __uint128_t;
+
+ /// The width estimation using a log10 algorithm.
+ ///
+ /// The algorithm is based on
+ /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+ /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
+ /// function requires its input to have at least one bit set the value of
+ /// zero is set to one. This means the first element of the lookup table is
+ /// zero.
+ static _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
+ _LIBCPP_ASSERT(__v > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true.");
+ // There's always a bit set in the upper 64-bits.
+ auto __t = (128 - std::__libcpp_clz(static_cast<uint64_t>(__v >> 64))) * 1233 >> 12;
+ _LIBCPP_ASSERT(__t >= __table<>::__pow10_128_offset, "Index out of bounds");
+ // __t is adjusted since the lookup table misses the lower entries.
+ return __t - (__v < __table<>::__pow10_128[__t - __table<>::__pow10_128_offset]) + 1;
+ }
+
+ static _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { return __itoa::__base_10_u128(__p, __v); }
+
+ // TODO FMT This pow function should get an index.
+ // By moving this to its own header it can be reused by the pow function in to_chars_base_10.
+ static _LIBCPP_HIDE_FROM_ABI decltype(__table<>::__pow10_128)& __pow() { return __table<>::__pow10_128; }
+};
+#endif
+
+template <typename _Tp>
inline _LIBCPP_HIDE_FROM_ABI bool
__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r)
{
@@ -271,6 +316,28 @@ __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type)
return {__last, errc::value_too_large};
}
+# ifndef _LIBCPP_HAS_NO_INT128
+template <>
+inline _LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type)
+{
+ // When the value fits in 64-bits use the 64-bit code path. This reduces
+ // the number of expensive calculations on 128-bit values.
+ //
+ // NOTE the 128-bit code path requires this optimization.
+ if(__value <= numeric_limits<uint64_t>::max())
+ return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type());
+
+ using __tx = __itoa::__traits<__uint128_t>;
+ auto __diff = __last - __first;
+
+ if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
+ return {__tx::__convert(__first, __value), errc(0)};
+ else
+ return {__last, errc::value_too_large};
+}
+#endif
+
template <typename _Tp>
inline _LIBCPP_HIDE_FROM_ABI to_chars_result
__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
@@ -493,7 +560,6 @@ to_chars(char* __first, char* __last, _Tp __value)
{
using _Type = __make_32_64_or_128_bit_t<_Tp>;
static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars");
- static_assert(sizeof(_Tp) <= sizeof(int64_t), "128-bit integral support isn't available yet in to_chars");
return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>());
}
@@ -504,7 +570,6 @@ to_chars(char* __first, char* __last, _Tp __value, int __base)
_LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
using _Type = __make_32_64_or_128_bit_t<_Tp>;
- static_assert(sizeof(_Tp) <= sizeof(int64_t), "128-bit integral support isn't available yet in to_chars");
return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>());
}
@@ -623,11 +688,11 @@ __from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
return __subject_seq_combinator(
__first, __last, __value,
- [](const char* _First, const char* _Last,
+ [](const char* __f, const char* __l,
_Tp& __val) -> from_chars_result {
__output_type __a, __b;
- auto __p = __tx::__read(_First, _Last, __a, __b);
- if (__p == _Last || !__in_pattern(*__p))
+ auto __p = __tx::__read(__f, __l, __a, __b);
+ if (__p == __l || !__in_pattern(*__p))
{
__output_type __m = numeric_limits<_Tp>::max();
if (__m >= __a && __m - __a >= __b)
@@ -659,22 +724,22 @@ __from_chars_integral(const char* __first, const char* __last, _Tp& __value,
return __subject_seq_combinator(
__first, __last, __value,
[](const char* __p, const char* __lastp, _Tp& __val,
- int _Base) -> from_chars_result {
+ int __b) -> from_chars_result {
using __tl = numeric_limits<_Tp>;
- auto __digits = __tl::digits / log2f(float(_Base));
- _Tp __a = __in_pattern(*__p++, _Base).__val, __b = 0;
+ auto __digits = __tl::digits / log2f(float(__b));
+ _Tp __x = __in_pattern(*__p++, __b).__val, __y = 0;
for (int __i = 1; __p != __lastp; ++__i, ++__p)
{
- if (auto __c = __in_pattern(*__p, _Base))
+ if (auto __c = __in_pattern(*__p, __b))
{
if (__i < __digits - 1)
- __a = __a * _Base + __c.__val;
+ __x = __x * __b + __c.__val;
else
{
- if (!__itoa::__mul_overflowed(__a, _Base, __a))
+ if (!__itoa::__mul_overflowed(__x, __b, __x))
++__p;
- __b = __c.__val;
+ __y = __c.__val;
break;
}
}
@@ -682,11 +747,11 @@ __from_chars_integral(const char* __first, const char* __last, _Tp& __value,
break;
}
- if (__p == __lastp || !__in_pattern(*__p, _Base))
+ if (__p == __lastp || !__in_pattern(*__p, __b))
{
- if (__tl::max() - __a >= __b)
+ if (__tl::max() - __x >= __y)
{
- __val = __a + __b;
+ __val = __x + __y;
return {__p, {}};
}
}
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index 9185d74c09c4..2af5fbcc5165 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -13,6 +13,8 @@
/*
chrono synopsis
+#include <compare> // C++20
+
namespace std
{
namespace chrono
@@ -325,11 +327,7 @@ struct last_spec;
class day;
constexpr bool operator==(const day& x, const day& y) noexcept;
-constexpr bool operator!=(const day& x, const day& y) noexcept;
-constexpr bool operator< (const day& x, const day& y) noexcept;
-constexpr bool operator> (const day& x, const day& y) noexcept;
-constexpr bool operator<=(const day& x, const day& y) noexcept;
-constexpr bool operator>=(const day& x, const day& y) noexcept;
+constexpr strong_ordering operator<=>(const day& x, const day& y) noexcept;
constexpr day operator+(const day& x, const days& y) noexcept;
constexpr day operator+(const days& x, const day& y) noexcept;
constexpr day operator-(const day& x, const days& y) noexcept;
@@ -715,9 +713,11 @@ constexpr chrono::year operator ""y(unsigned lo
#include <__chrono/year_month_day.h>
#include <__chrono/year_month_weekday.h>
#include <__config>
-#include <compare>
#include <version>
+// standard-mandated includes
+#include <compare>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
diff --git a/libcxx/include/cmath b/libcxx/include/cmath
index 2d22151684e0..4d81eed339d8 100644
--- a/libcxx/include/cmath
+++ b/libcxx/include/cmath
@@ -530,9 +530,9 @@ using ::tgammal _LIBCPP_USING_IF_EXISTS;
using ::truncl _LIBCPP_USING_IF_EXISTS;
#if _LIBCPP_STD_VER > 14
-inline _LIBCPP_INLINE_VISIBILITY float hypot( float x, float y, float z ) { return sqrt(x*x + y*y + z*z); }
-inline _LIBCPP_INLINE_VISIBILITY double hypot( double x, double y, double z ) { return sqrt(x*x + y*y + z*z); }
-inline _LIBCPP_INLINE_VISIBILITY long double hypot( long double x, long double y, long double z ) { return sqrt(x*x + y*y + z*z); }
+inline _LIBCPP_INLINE_VISIBILITY float hypot( float __x, float __y, float __z ) { return sqrt(__x*__x + __y*__y + __z*__z); }
+inline _LIBCPP_INLINE_VISIBILITY double hypot( double __x, double __y, double __z ) { return sqrt(__x*__x + __y*__y + __z*__z); }
+inline _LIBCPP_INLINE_VISIBILITY long double hypot( long double __x, long double __y, long double __z ) { return sqrt(__x*__x + __y*__y + __z*__z); }
template <class _A1, class _A2, class _A3>
inline _LIBCPP_INLINE_VISIBILITY
diff --git a/libcxx/include/codecvt b/libcxx/include/codecvt
index 3e5110a008e4..9f18a7b1a989 100644
--- a/libcxx/include/codecvt
+++ b/libcxx/include/codecvt
@@ -92,10 +92,10 @@ public:
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
_LIBCPP_INLINE_VISIBILITY
- explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode,
- codecvt_mode _Mode)
- : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
- _Mode_(_Mode) {}
+ explicit __codecvt_utf8(size_t __refs, unsigned long __maxcode,
+ codecvt_mode __mode)
+ : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(__maxcode),
+ _Mode_(__mode) {}
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
virtual result
@@ -130,10 +130,10 @@ public:
typedef mbstate_t state_type;
_LIBCPP_INLINE_VISIBILITY
- explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode,
- codecvt_mode _Mode)
- : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
- _Mode_(_Mode) {}
+ explicit __codecvt_utf8(size_t __refs, unsigned long __maxcode,
+ codecvt_mode __mode)
+ : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(__maxcode),
+ _Mode_(__mode) {}
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
@@ -168,10 +168,10 @@ public:
typedef mbstate_t state_type;
_LIBCPP_INLINE_VISIBILITY
- explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode,
- codecvt_mode _Mode)
- : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
- _Mode_(_Mode) {}
+ explicit __codecvt_utf8(size_t __refs, unsigned long __maxcode,
+ codecvt_mode __mode)
+ : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(__maxcode),
+ _Mode_(__mode) {}
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
@@ -229,10 +229,10 @@ public:
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
_LIBCPP_INLINE_VISIBILITY
- explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
- codecvt_mode _Mode)
- : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
- _Mode_(_Mode) {}
+ explicit __codecvt_utf16(size_t __refs, unsigned long __maxcode,
+ codecvt_mode __mode)
+ : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(__maxcode),
+ _Mode_(__mode) {}
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
virtual result
@@ -268,10 +268,10 @@ public:
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
_LIBCPP_INLINE_VISIBILITY
- explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
- codecvt_mode _Mode)
- : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
- _Mode_(_Mode) {}
+ explicit __codecvt_utf16(size_t __refs, unsigned long __maxcode,
+ codecvt_mode __mode)
+ : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(__maxcode),
+ _Mode_(__mode) {}
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
virtual result
@@ -306,10 +306,10 @@ public:
typedef mbstate_t state_type;
_LIBCPP_INLINE_VISIBILITY
- explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
- codecvt_mode _Mode)
- : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
- _Mode_(_Mode) {}
+ explicit __codecvt_utf16(size_t __refs, unsigned long __maxcode,
+ codecvt_mode __mode)
+ : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(__maxcode),
+ _Mode_(__mode) {}
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
@@ -344,10 +344,10 @@ public:
typedef mbstate_t state_type;
_LIBCPP_INLINE_VISIBILITY
- explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
- codecvt_mode _Mode)
- : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
- _Mode_(_Mode) {}
+ explicit __codecvt_utf16(size_t __refs, unsigned long __maxcode,
+ codecvt_mode __mode)
+ : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(__maxcode),
+ _Mode_(__mode) {}
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
@@ -382,10 +382,10 @@ public:
typedef mbstate_t state_type;
_LIBCPP_INLINE_VISIBILITY
- explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
- codecvt_mode _Mode)
- : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
- _Mode_(_Mode) {}
+ explicit __codecvt_utf16(size_t __refs, unsigned long __maxcode,
+ codecvt_mode __mode)
+ : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(__maxcode),
+ _Mode_(__mode) {}
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
@@ -420,10 +420,10 @@ public:
typedef mbstate_t state_type;
_LIBCPP_INLINE_VISIBILITY
- explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
- codecvt_mode _Mode)
- : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
- _Mode_(_Mode) {}
+ explicit __codecvt_utf16(size_t __refs, unsigned long __maxcode,
+ codecvt_mode __mode)
+ : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(__maxcode),
+ _Mode_(__mode) {}
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
@@ -481,10 +481,10 @@ public:
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
_LIBCPP_INLINE_VISIBILITY
- explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode,
- codecvt_mode _Mode)
- : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
- _Mode_(_Mode) {}
+ explicit __codecvt_utf8_utf16(size_t __refs, unsigned long __maxcode,
+ codecvt_mode __mode)
+ : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(__maxcode),
+ _Mode_(__mode) {}
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
virtual result
@@ -519,10 +519,10 @@ public:
typedef mbstate_t state_type;
_LIBCPP_INLINE_VISIBILITY
- explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode,
- codecvt_mode _Mode)
- : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
- _Mode_(_Mode) {}
+ explicit __codecvt_utf8_utf16(size_t __refs, unsigned long __maxcode,
+ codecvt_mode __mode)
+ : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(__maxcode),
+ _Mode_(__mode) {}
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
@@ -557,10 +557,10 @@ public:
typedef mbstate_t state_type;
_LIBCPP_INLINE_VISIBILITY
- explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode,
- codecvt_mode _Mode)
- : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
- _Mode_(_Mode) {}
+ explicit __codecvt_utf8_utf16(size_t __refs, unsigned long __maxcode,
+ codecvt_mode __mode)
+ : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(__maxcode),
+ _Mode_(__mode) {}
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
diff --git a/libcxx/include/condition_variable b/libcxx/include/condition_variable
index dfcb7160565b..92088f3e1b22 100644
--- a/libcxx/include/condition_variable
+++ b/libcxx/include/condition_variable
@@ -261,7 +261,7 @@ condition_variable_any::wait_for(_Lock& __lock,
}
_LIBCPP_FUNC_VIS
-void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
+void notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>);
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/deque b/libcxx/include/deque
index d8f48f07954c..0d7eb9aa9316 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -1464,12 +1464,10 @@ public:
iterator insert(const_iterator __p, size_type __n, const value_type& __v);
template <class _InputIter>
iterator insert(const_iterator __p, _InputIter __f, _InputIter __l,
- typename enable_if<__is_cpp17_input_iterator<_InputIter>::value
- &&!__is_cpp17_forward_iterator<_InputIter>::value>::type* = 0);
+ typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type* = 0);
template <class _ForwardIterator>
iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
- typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value
- &&!__is_cpp17_bidirectional_iterator<_ForwardIterator>::value>::type* = 0);
+ typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0);
template <class _BiIter>
iterator insert(const_iterator __p, _BiIter __f, _BiIter __l,
typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type* = 0);
@@ -1556,8 +1554,7 @@ public:
template <class _InpIter>
void __append(_InpIter __f, _InpIter __l,
- typename enable_if<__is_cpp17_input_iterator<_InpIter>::value &&
- !__is_cpp17_forward_iterator<_InpIter>::value>::type* = 0);
+ typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type* = 0);
template <class _ForIter>
void __append(_ForIter __f, _ForIter __l,
typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type* = 0);
@@ -2266,8 +2263,7 @@ template <class _Tp, class _Allocator>
template <class _InputIter>
typename deque<_Tp, _Allocator>::iterator
deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
- typename enable_if<__is_cpp17_input_iterator<_InputIter>::value
- &&!__is_cpp17_forward_iterator<_InputIter>::value>::type*)
+ typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type*)
{
__split_buffer<value_type, allocator_type&> __buf(__base::__alloc());
__buf.__construct_at_end(__f, __l);
@@ -2279,8 +2275,7 @@ template <class _Tp, class _Allocator>
template <class _ForwardIterator>
typename deque<_Tp, _Allocator>::iterator
deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
- typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value
- &&!__is_cpp17_bidirectional_iterator<_ForwardIterator>::value>::type*)
+ typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type*)
{
size_type __n = _VSTD::distance(__f, __l);
__split_buffer<value_type, allocator_type&> __buf(__n, 0, __base::__alloc());
@@ -2362,8 +2357,7 @@ template <class _Tp, class _Allocator>
template <class _InpIter>
void
deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
- typename enable_if<__is_cpp17_input_iterator<_InpIter>::value &&
- !__is_cpp17_forward_iterator<_InpIter>::value>::type*)
+ typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type*)
{
for (; __f != __l; ++__f)
#ifdef _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/exception b/libcxx/include/exception
index 412e02af3822..7b514e5dca54 100644
--- a/libcxx/include/exception
+++ b/libcxx/include/exception
@@ -216,7 +216,7 @@ _LIBCPP_FUNC_VIS void swap(exception_ptr&, exception_ptr&) _NOEXCEPT;
_LIBCPP_FUNC_VIS exception_ptr __copy_exception_ptr(void *__except, const void* __ptr);
_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr p);
+_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
// This is a built-in template function which automagically extracts the required
// information.
@@ -310,7 +310,7 @@ template <class _Ep>
inline _LIBCPP_INLINE_VISIBILITY
void
rethrow_if_nested(const _Ep& __e,
- typename enable_if< __can_dynamic_cast<_Ep, nested_exception>::value>::type* = 0)
+ __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value>* = 0)
{
const nested_exception* __nep = dynamic_cast<const nested_exception*>(_VSTD::addressof(__e));
if (__nep)
@@ -321,7 +321,7 @@ template <class _Ep>
inline _LIBCPP_INLINE_VISIBILITY
void
rethrow_if_nested(const _Ep&,
- typename enable_if<!__can_dynamic_cast<_Ep, nested_exception>::value>::type* = 0)
+ __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value>* = 0)
{
}
diff --git a/libcxx/include/experimental/functional b/libcxx/include/experimental/functional
index 04f195d3cf24..12440744ca50 100644
--- a/libcxx/include/experimental/functional
+++ b/libcxx/include/experimental/functional
@@ -62,6 +62,7 @@ inline namespace fundamentals_v1 {
#include <__assert> // all public C++ headers provide the assertion handler
#include <__debug>
+#include <__functional/identity.h>
#include <__memory/uses_allocator.h>
#include <array>
#include <experimental/__config>
@@ -104,9 +105,8 @@ public:
pair<_ForwardIterator2, _ForwardIterator2>
operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const
{
- return _VSTD::__search(__f, __l, __first_, __last_, __pred_,
- typename iterator_traits<_ForwardIterator>::iterator_category(),
- typename iterator_traits<_ForwardIterator2>::iterator_category());
+ auto __proj = __identity();
+ return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj);
}
private:
diff --git a/libcxx/include/experimental/simd b/libcxx/include/experimental/simd
index 9b55cc009986..f77ce59bb269 100644
--- a/libcxx/include/experimental/simd
+++ b/libcxx/include/experimental/simd
@@ -1242,32 +1242,32 @@ _Tp reduce(const simd<_Tp, _Abi>&, _BinaryOp = _BinaryOp());
template <class _MaskType, class _SimdType, class _BinaryOp>
typename _SimdType::value_type
reduce(const const_where_expression<_MaskType, _SimdType>&,
- typename _SimdType::value_type neutral_element, _BinaryOp binary_op);
+ typename _SimdType::value_type __neutral_element, _BinaryOp);
template <class _MaskType, class _SimdType>
typename _SimdType::value_type
reduce(const const_where_expression<_MaskType, _SimdType>&,
- plus<typename _SimdType::value_type> binary_op = {});
+ plus<typename _SimdType::value_type> = {});
template <class _MaskType, class _SimdType>
typename _SimdType::value_type
reduce(const const_where_expression<_MaskType, _SimdType>&,
- multiplies<typename _SimdType::value_type> binary_op);
+ multiplies<typename _SimdType::value_type>);
template <class _MaskType, class _SimdType>
typename _SimdType::value_type
reduce(const const_where_expression<_MaskType, _SimdType>&,
- bit_and<typename _SimdType::value_type> binary_op);
+ bit_and<typename _SimdType::value_type>);
template <class _MaskType, class _SimdType>
typename _SimdType::value_type
reduce(const const_where_expression<_MaskType, _SimdType>&,
- bit_or<typename _SimdType::value_type> binary_op);
+ bit_or<typename _SimdType::value_type>);
template <class _MaskType, class _SimdType>
typename _SimdType::value_type
reduce(const const_where_expression<_MaskType, _SimdType>&,
- bit_xor<typename _SimdType::value_type> binary_op);
+ bit_xor<typename _SimdType::value_type>);
template <class _Tp, class _Abi>
_Tp hmin(const simd<_Tp, _Abi>&);
diff --git a/libcxx/include/ext/hash_map b/libcxx/include/ext/hash_map
index 8afe12f6319b..a581d5c550c4 100644
--- a/libcxx/include/ext/hash_map
+++ b/libcxx/include/ext/hash_map
@@ -605,7 +605,7 @@ public:
{return __table_.bucket_size(__n);}
_LIBCPP_INLINE_VISIBILITY
- void resize(size_type __n) {__table_.rehash(__n);}
+ void resize(size_type __n) {__table_.__rehash_unique(__n);}
private:
__node_holder __construct_node(const key_type& __k);
@@ -616,7 +616,7 @@ hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
size_type __n, const hasher& __hf, const key_equal& __eql)
: __table_(__hf, __eql)
{
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -625,7 +625,7 @@ hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
const allocator_type& __a)
: __table_(__hf, __eql, __a)
{
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -643,7 +643,7 @@ hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
const hasher& __hf, const key_equal& __eql)
: __table_(__hf, __eql)
{
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
insert(__first, __last);
}
@@ -654,7 +654,7 @@ hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
: __table_(__hf, __eql, __a)
{
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
insert(__first, __last);
}
@@ -663,7 +663,7 @@ hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
const hash_map& __u)
: __table_(__u.__table_)
{
- __table_.rehash(__u.bucket_count());
+ __table_.__rehash_unique(__u.bucket_count());
insert(__u.begin(), __u.end());
}
@@ -874,7 +874,7 @@ public:
{return __table_.bucket_size(__n);}
_LIBCPP_INLINE_VISIBILITY
- void resize(size_type __n) {__table_.rehash(__n);}
+ void resize(size_type __n) {__table_.__rehash_multi(__n);}
};
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -882,7 +882,7 @@ hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
size_type __n, const hasher& __hf, const key_equal& __eql)
: __table_(__hf, __eql)
{
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -891,7 +891,7 @@ hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
const allocator_type& __a)
: __table_(__hf, __eql, __a)
{
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -909,7 +909,7 @@ hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
const hasher& __hf, const key_equal& __eql)
: __table_(__hf, __eql)
{
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
insert(__first, __last);
}
@@ -920,7 +920,7 @@ hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
: __table_(__hf, __eql, __a)
{
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
insert(__first, __last);
}
@@ -929,7 +929,7 @@ hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
const hash_multimap& __u)
: __table_(__u.__table_)
{
- __table_.rehash(__u.bucket_count());
+ __table_.__rehash_multi(__u.bucket_count());
insert(__u.begin(), __u.end());
}
diff --git a/libcxx/include/ext/hash_set b/libcxx/include/ext/hash_set
index 433c13f80bb2..5823b5fb9476 100644
--- a/libcxx/include/ext/hash_set
+++ b/libcxx/include/ext/hash_set
@@ -333,7 +333,7 @@ public:
size_type elems_in_bucket(size_type __n) const {return __table_.bucket_size(__n);}
_LIBCPP_INLINE_VISIBILITY
- void resize(size_type __n) {__table_.rehash(__n);}
+ void resize(size_type __n) {__table_.__rehash_unique(__n);}
};
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -341,7 +341,7 @@ hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n,
const hasher& __hf, const key_equal& __eql)
: __table_(__hf, __eql)
{
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
}
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -349,7 +349,7 @@ hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n,
const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
: __table_(__hf, __eql, __a)
{
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
}
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -367,7 +367,7 @@ hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
const hasher& __hf, const key_equal& __eql)
: __table_(__hf, __eql)
{
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
insert(__first, __last);
}
@@ -378,7 +378,7 @@ hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
: __table_(__hf, __eql, __a)
{
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
insert(__first, __last);
}
@@ -387,7 +387,7 @@ hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
const hash_set& __u)
: __table_(__u.__table_)
{
- __table_.rehash(__u.bucket_count());
+ __table_.__rehash_unique(__u.bucket_count());
insert(__u.begin(), __u.end());
}
@@ -553,7 +553,7 @@ public:
size_type elems_in_bucket(size_type __n) const {return __table_.bucket_size(__n);}
_LIBCPP_INLINE_VISIBILITY
- void resize(size_type __n) {__table_.rehash(__n);}
+ void resize(size_type __n) {__table_.__rehash_multi(__n);}
};
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -561,7 +561,7 @@ hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
size_type __n, const hasher& __hf, const key_equal& __eql)
: __table_(__hf, __eql)
{
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
}
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -570,7 +570,7 @@ hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
const allocator_type& __a)
: __table_(__hf, __eql, __a)
{
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
}
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -588,7 +588,7 @@ hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
const hasher& __hf, const key_equal& __eql)
: __table_(__hf, __eql)
{
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
insert(__first, __last);
}
@@ -599,7 +599,7 @@ hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
: __table_(__hf, __eql, __a)
{
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
insert(__first, __last);
}
@@ -608,7 +608,7 @@ hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
const hash_multiset& __u)
: __table_(__u.__table_)
{
- __table_.rehash(__u.bucket_count());
+ __table_.__rehash_multi(__u.bucket_count());
insert(__u.begin(), __u.end());
}
diff --git a/libcxx/include/format b/libcxx/include/format
index bf51edd91ece..60197d24523f 100644
--- a/libcxx/include/format
+++ b/libcxx/include/format
@@ -36,13 +36,13 @@ namespace std {
// [format.functions], formatting functions
template<class... Args>
- string format(format-string<Args...> fmt, const Args&... args);
+ string format(format-string<Args...> fmt, Args&&... args);
template<class... Args>
- wstring format(wformat-string<Args...> fmt, const Args&... args);
+ wstring format(wformat-string<Args...> fmt, Args&&... args);
template<class... Args>
- string format(const locale& loc, format-string<Args...> fmt, const Args&... args);
+ string format(const locale& loc, format-string<Args...> fmt, Args&&... args);
template<class... Args>
- wstring format(const locale& loc, wformat-string<Args...> fmt, const Args&... args);
+ wstring format(const locale& loc, wformat-string<Args...> fmt, Args&&... args);
string vformat(string_view fmt, format_args args);
wstring vformat(wstring_view fmt, wformat_args args);
@@ -50,13 +50,13 @@ namespace std {
wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);
template<class Out, class... Args>
- Out format_to(Out out, format-string<Args...> fmt, const Args&... args);
+ Out format_to(Out out, format-string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
- Out format_to(Out out, wformat-string<Args...> fmt, const Args&... args);
+ Out format_to(Out out, wformat-string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
- Out format_to(Out out, const locale& loc, format-string<Args...> fmt, const Args&... args);
+ Out format_to(Out out, const locale& loc, format-string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
- Out format_to(Out out, const locale& loc, wformat-string<Args...> fmt, const Args&... args);
+ Out format_to(Out out, const locale& loc, wformat-string<Args...> fmt, Args&&... args);
template<class Out>
Out vformat_to(Out out, string_view fmt, format_args args);
@@ -75,27 +75,27 @@ namespace std {
};
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
- format-string<Args...> fmt, const Args&... args);
+ format-string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
- wformat-string<Args...> fmt, const Args&... args);
+ wformat-string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
const locale& loc, format-string<Args...> fmt,
- const Args&... args);
+ Args&&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
const locale& loc, wformat-string<Args...> fmt,
- const Args&... args);
+ Args&&... args);
template<class... Args>
- size_t formatted_size(format-string<Args...> fmt, const Args&... args);
+ size_t formatted_size(format-string<Args...> fmt, Args&&... args);
template<class... Args>
- size_t formatted_size(wformat-string<Args...> fmt, const Args&... args);
+ size_t formatted_size(wformat-string<Args...> fmt, Args&&... args);
template<class... Args>
- size_t formatted_size(const locale& loc, format-string<Args...> fmt, const Args&... args);
+ size_t formatted_size(const locale& loc, format-string<Args...> fmt, Args&&... args);
template<class... Args>
- size_t formatted_size(const locale& loc, wformat-string<Args...> fmt, const Args&... args);
+ size_t formatted_size(const locale& loc, wformat-string<Args...> fmt, Args&&... args);
// [format.formatter], formatter
template<class T, class charT = char> struct formatter;
@@ -117,10 +117,10 @@ namespace std {
template<class Context = format_context, class... Args>
format-arg-store<Context, Args...>
- make_format_args(const Args&... args);
+ make_format_args(Args&&... args);
template<class... Args>
format-arg-store<wformat_context, Args...>
- make_wformat_args(const Args&... args);
+ make_wformat_args(Args&&... args);
// [format.error], class format_error
class format_error;
@@ -190,26 +190,15 @@ using format_args = basic_format_args<format_context>;
using wformat_args = basic_format_args<wformat_context>;
#endif
-// TODO FMT This helper wrapper can probably be removed after P2418 has been
-// implemented.
-template <class _Context, class... _Args>
-_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...>
-__make_format_args(_Args&&... __args) {
- return _VSTD::__format_arg_store<_Context, _Args...>(
- _VSTD::forward<_Args>(__args)...);
-}
-
-// TODO FMT After P2418 specify the return type instead of using auto.
template <class _Context = format_context, class... _Args>
-_LIBCPP_HIDE_FROM_ABI auto make_format_args(const _Args&... __args) {
- return _VSTD::__make_format_args<_Context>(__args...);
+_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&&... __args) {
+ return _VSTD::__format_arg_store<_Context, _Args...>(__args...);
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-// TODO FMT After P2418 specify the return type instead of using auto.
template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI auto make_wformat_args(const _Args&... __args) {
- return _VSTD::make_format_args<wformat_context>(__args...);
+_LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...> make_wformat_args(_Args&&... __args) {
+ return _VSTD::__format_arg_store<wformat_context, _Args...>(__args...);
}
#endif
@@ -387,6 +376,7 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end,
__format::__parse_number_result __r =
__format::__parse_arg_id(__begin, __end, __parse_ctx);
+ bool __parse = *__r.__ptr == _CharT(':');
switch (*__r.__ptr) {
case _CharT(':'):
// The arg-id has a format-specifier, advance the input to the format-spec.
@@ -406,7 +396,7 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end,
if (__type == __arg_t::__handle)
__ctx.__handle(__r.__value).__parse(__parse_ctx);
else
- __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type);
+ __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type);
} else
_VSTD::visit_format_arg(
[&](auto __arg) {
@@ -416,7 +406,8 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end,
__arg.format(__parse_ctx, __ctx);
else {
formatter<decltype(__arg), _CharT> __formatter;
- __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
+ if (__parse)
+ __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
__ctx.advance_to(__formatter.format(__arg, __ctx));
}
},
@@ -563,7 +554,7 @@ vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
template <output_iterator<const char&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
-format_to(_OutIt __out_it, __format_string_t<_Args...> __fmt, const _Args&... __args) {
+format_to(_OutIt __out_it, __format_string_t<_Args...> __fmt, _Args&&... __args) {
return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.__str_,
_VSTD::make_format_args(__args...));
}
@@ -571,7 +562,7 @@ format_to(_OutIt __out_it, __format_string_t<_Args...> __fmt, const _Args&... __
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
-format_to(_OutIt __out_it, __wformat_string_t<_Args...> __fmt, const _Args&... __args) {
+format_to(_OutIt __out_it, __wformat_string_t<_Args...> __fmt, _Args&&... __args) {
return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.__str_,
_VSTD::make_wformat_args(__args...));
}
@@ -595,14 +586,14 @@ vformat(wstring_view __fmt, wformat_args __args) {
template <class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(__format_string_t<_Args...> __fmt,
- const _Args&... __args) {
+ _Args&&... __args) {
return _VSTD::vformat(__fmt.__str_, _VSTD::make_format_args(__args...));
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
-format(__wformat_string_t<_Args...> __fmt, const _Args&... __args) {
+format(__wformat_string_t<_Args...> __fmt, _Args&&... __args) {
return _VSTD::vformat(__fmt.__str_, _VSTD::make_wformat_args(__args...));
}
#endif
@@ -619,7 +610,7 @@ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it,
template <output_iterator<const char&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
-format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, __format_string_t<_Args...> __fmt, const _Args&... __args) {
+format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, __format_string_t<_Args...> __fmt, _Args&&... __args) {
return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, __fmt.__str_, _VSTD::make_format_args(__args...));
}
@@ -627,7 +618,7 @@ format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, __format_string_t<_A
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, __wformat_string_t<_Args...> __fmt,
- const _Args&... __args) {
+ _Args&&... __args) {
return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, __fmt.__str_, _VSTD::make_wformat_args(__args...));
}
#endif
@@ -642,14 +633,14 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt,
template <class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
-formatted_size(__format_string_t<_Args...> __fmt, const _Args&... __args) {
+formatted_size(__format_string_t<_Args...> __fmt, _Args&&... __args) {
return _VSTD::__vformatted_size(__fmt.__str_, basic_format_args{_VSTD::make_format_args(__args...)});
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
-formatted_size(__wformat_string_t<_Args...> __fmt, const _Args&... __args) {
+formatted_size(__wformat_string_t<_Args...> __fmt, _Args&&... __args) {
return _VSTD::__vformatted_size(__fmt.__str_, basic_format_args{_VSTD::make_wformat_args(__args...)});
}
#endif
@@ -694,7 +685,7 @@ _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt v
template <output_iterator<const char&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
-format_to(_OutIt __out_it, locale __loc, __format_string_t<_Args...> __fmt, const _Args&... __args) {
+format_to(_OutIt __out_it, locale __loc, __format_string_t<_Args...> __fmt, _Args&&... __args) {
return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.__str_,
_VSTD::make_format_args(__args...));
}
@@ -702,7 +693,7 @@ format_to(_OutIt __out_it, locale __loc, __format_string_t<_Args...> __fmt, cons
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
-format_to(_OutIt __out_it, locale __loc, __wformat_string_t<_Args...> __fmt, const _Args&... __args) {
+format_to(_OutIt __out_it, locale __loc, __wformat_string_t<_Args...> __fmt, _Args&&... __args) {
return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.__str_,
_VSTD::make_wformat_args(__args...));
}
@@ -729,7 +720,7 @@ vformat(locale __loc, wstring_view __fmt, wformat_args __args) {
template <class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(locale __loc,
__format_string_t<_Args...> __fmt,
- const _Args&... __args) {
+ _Args&&... __args) {
return _VSTD::vformat(_VSTD::move(__loc), __fmt.__str_,
_VSTD::make_format_args(__args...));
}
@@ -737,7 +728,7 @@ _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string f
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
-format(locale __loc, __wformat_string_t<_Args...> __fmt, const _Args&... __args) {
+format(locale __loc, __wformat_string_t<_Args...> __fmt, _Args&&... __args) {
return _VSTD::vformat(_VSTD::move(__loc), __fmt.__str_,
_VSTD::make_wformat_args(__args...));
}
@@ -757,7 +748,7 @@ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it,
template <output_iterator<const char&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, __format_string_t<_Args...> __fmt,
- const _Args&... __args) {
+ _Args&&... __args) {
return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.__str_,
_VSTD::make_format_args(__args...));
}
@@ -766,7 +757,7 @@ format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, __form
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, __wformat_string_t<_Args...> __fmt,
- const _Args&... __args) {
+ _Args&&... __args) {
return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.__str_,
_VSTD::make_wformat_args(__args...));
}
@@ -783,14 +774,14 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_
template <class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
-formatted_size(locale __loc, __format_string_t<_Args...> __fmt, const _Args&... __args) {
+formatted_size(locale __loc, __format_string_t<_Args...> __fmt, _Args&&... __args) {
return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.__str_, basic_format_args{_VSTD::make_format_args(__args...)});
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
-formatted_size(locale __loc, __wformat_string_t<_Args...> __fmt, const _Args&... __args) {
+formatted_size(locale __loc, __wformat_string_t<_Args...> __fmt, _Args&&... __args) {
return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.__str_, basic_format_args{_VSTD::make_wformat_args(__args...)});
}
#endif
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 6a7272027351..aab3b8715d01 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -703,15 +703,11 @@ public:
template <class _InputIterator>
forward_list(_InputIterator __f, _InputIterator __l,
- typename enable_if<
- __is_cpp17_input_iterator<_InputIterator>::value
- >::type* = nullptr);
+ __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>* = nullptr);
template <class _InputIterator>
forward_list(_InputIterator __f, _InputIterator __l,
const allocator_type& __a,
- typename enable_if<
- __is_cpp17_input_iterator<_InputIterator>::value
- >::type* = nullptr);
+ __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>* = nullptr);
forward_list(const forward_list& __x);
forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a);
@@ -743,11 +739,7 @@ public:
// ~forward_list() = default;
template <class _InputIterator>
- typename enable_if
- <
- __is_cpp17_input_iterator<_InputIterator>::value,
- void
- >::type
+ __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>
assign(_InputIterator __f, _InputIterator __l);
void assign(size_type __n, const value_type& __v);
@@ -823,12 +815,8 @@ public:
iterator insert_after(const_iterator __p, const value_type& __v);
iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
template <class _InputIterator>
- _LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- __is_cpp17_input_iterator<_InputIterator>::value,
- iterator
- >::type
+ _LIBCPP_INLINE_VISIBILITY
+ __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, iterator>
insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
iterator erase_after(const_iterator __p);
@@ -977,9 +965,7 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
template <class _Tp, class _Alloc>
template <class _InputIterator>
forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
- typename enable_if<
- __is_cpp17_input_iterator<_InputIterator>::value
- >::type*)
+ __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>*)
{
insert_after(cbefore_begin(), __f, __l);
}
@@ -988,9 +974,7 @@ template <class _Tp, class _Alloc>
template <class _InputIterator>
forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
const allocator_type& __a,
- typename enable_if<
- __is_cpp17_input_iterator<_InputIterator>::value
- >::type*)
+ __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>*)
: base(__a)
{
insert_after(cbefore_begin(), __f, __l);
@@ -1100,11 +1084,7 @@ forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
template <class _Tp, class _Alloc>
template <class _InputIterator>
-typename enable_if
-<
- __is_cpp17_input_iterator<_InputIterator>::value,
- void
->::type
+__enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>
forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
{
iterator __i = before_begin();
@@ -1296,11 +1276,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
template <class _Tp, class _Alloc>
template <class _InputIterator>
-typename enable_if
-<
- __is_cpp17_input_iterator<_InputIterator>::value,
- typename forward_list<_Tp, _Alloc>::iterator
->::type
+__enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, typename forward_list<_Tp, _Alloc>::iterator>
forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
_InputIterator __f, _InputIterator __l)
{
diff --git a/libcxx/include/future b/libcxx/include/future
index f4a5b43eef08..cedab3608ad2 100644
--- a/libcxx/include/future
+++ b/libcxx/include/future
@@ -525,12 +525,12 @@ _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
#ifndef _LIBCPP_NO_EXCEPTIONS
_LIBCPP_AVAILABILITY_FUTURE_ERROR
#endif
-void __throw_future_error(future_errc _Ev)
+void __throw_future_error(future_errc __ev)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
- throw future_error(make_error_code(_Ev));
+ throw future_error(make_error_code(__ev));
#else
- ((void)_Ev);
+ ((void)__ev);
_VSTD::abort();
#endif
}
@@ -1106,7 +1106,7 @@ future<_Rp>::future(__assoc_state<_Rp>* __state)
struct __release_shared_count
{
- void operator()(__shared_count* p) {p->__release_shared();}
+ void operator()(__shared_count* __p) {__p->__release_shared();}
};
template <class _Rp>
diff --git a/libcxx/include/list b/libcxx/include/list
index d75b15c060be..1db29d14b842 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -870,10 +870,10 @@ public:
template <class _InpIter>
list(_InpIter __f, _InpIter __l,
- typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0);
+ __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0);
template <class _InpIter>
list(_InpIter __f, _InpIter __l, const allocator_type& __a,
- typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0);
+ __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0);
list(const list& __c);
list(const list& __c, const __type_identity_t<allocator_type>& __a);
@@ -905,7 +905,7 @@ public:
template <class _InpIter>
void assign(_InpIter __f, _InpIter __l,
- typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0);
+ __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0);
void assign(size_type __n, const value_type& __x);
_LIBCPP_INLINE_VISIBILITY
@@ -1022,7 +1022,7 @@ public:
iterator insert(const_iterator __p, size_type __n, const value_type& __x);
template <class _InpIter>
iterator insert(const_iterator __p, _InpIter __f, _InpIter __l,
- typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0);
+ __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0);
_LIBCPP_INLINE_VISIBILITY
void swap(list& __c)
@@ -1220,7 +1220,7 @@ list<_Tp, _Alloc>::list(size_type __n, const value_type& __x)
template <class _Tp, class _Alloc>
template <class _InpIter>
list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l,
- typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*)
+ __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*)
{
_VSTD::__debug_db_insert_c(this);
for (; __f != __l; ++__f)
@@ -1230,7 +1230,7 @@ list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l,
template <class _Tp, class _Alloc>
template <class _InpIter>
list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a,
- typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*)
+ __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*)
: base(__a)
{
_VSTD::__debug_db_insert_c(this);
@@ -1355,7 +1355,7 @@ template <class _Tp, class _Alloc>
template <class _InpIter>
void
list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l,
- typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*)
+ __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*)
{
iterator __i = begin();
iterator __e = end();
@@ -1460,7 +1460,7 @@ template <class _Tp, class _Alloc>
template <class _InpIter>
typename list<_Tp, _Alloc>::iterator
list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
- typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*)
+ __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*)
{
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
"list::insert(iterator, range) called with an iterator not referring to this list");
diff --git a/libcxx/include/map b/libcxx/include/map
index 106ed5259ed9..e1d5fa8a25d8 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -582,9 +582,9 @@ public:
_NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
: _Compare() {}
_LIBCPP_INLINE_VISIBILITY
- __map_value_compare(_Compare c)
+ __map_value_compare(_Compare __c)
_NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
- : _Compare(c) {}
+ : _Compare(__c) {}
_LIBCPP_INLINE_VISIBILITY
const _Compare& key_comp() const _NOEXCEPT {return *this;}
_LIBCPP_INLINE_VISIBILITY
@@ -627,9 +627,9 @@ public:
_NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
: comp() {}
_LIBCPP_INLINE_VISIBILITY
- __map_value_compare(_Compare c)
+ __map_value_compare(_Compare __c)
_NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
- : comp(c) {}
+ : comp(__c) {}
_LIBCPP_INLINE_VISIBILITY
const _Compare& key_comp() const _NOEXCEPT {return comp;}
@@ -792,9 +792,7 @@ public:
}
template <class _ValueTp,
- class = typename enable_if<
- __is_same_uncvref<_ValueTp, value_type>::value
- >::type
+ class = __enable_if_t<__is_same_uncvref<_ValueTp, value_type>::value>
>
_LIBCPP_INLINE_VISIBILITY
__value_type& operator=(_ValueTp&& __v)
@@ -992,7 +990,7 @@ public:
protected:
key_compare comp;
- _LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {}
+ _LIBCPP_INLINE_VISIBILITY value_compare(key_compare __c) : comp(__c) {}
public:
_LIBCPP_INLINE_VISIBILITY
bool operator()(const value_type& __x, const value_type& __y) const
@@ -1230,13 +1228,13 @@ public:
}
template <class _Pp,
- class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+ class = __enable_if_t<is_constructible<value_type, _Pp>::value> >
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> insert(_Pp&& __p)
{return __tree_.__insert_unique(_VSTD::forward<_Pp>(__p));}
template <class _Pp,
- class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+ class = __enable_if_t<is_constructible<value_type, _Pp>::value> >
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __pos, _Pp&& __p)
{return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));}
@@ -1456,11 +1454,11 @@ public:
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
find(const _K2& __k) {return __tree_.find(__k);}
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, const_iterator>
find(const _K2& __k) const {return __tree_.find(__k);}
#endif
@@ -1470,7 +1468,7 @@ public:
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, size_type>
count(const _K2& __k) const {return __tree_.__count_multi(__k);}
#endif
@@ -1479,7 +1477,7 @@ public:
bool contains(const key_type& __k) const {return find(__k) != end();}
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, bool>
contains(const _K2& __k) const { return find(__k) != end(); }
#endif // _LIBCPP_STD_VER > 17
@@ -1492,12 +1490,12 @@ public:
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);}
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, const_iterator>
lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
#endif
@@ -1510,11 +1508,11 @@ public:
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);}
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, const_iterator>
upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
#endif
@@ -1527,11 +1525,11 @@ public:
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, pair<iterator,iterator>>
equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);}
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, pair<const_iterator,const_iterator>>
equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
#endif
@@ -1769,7 +1767,7 @@ public:
key_compare comp;
_LIBCPP_INLINE_VISIBILITY
- value_compare(key_compare c) : comp(c) {}
+ value_compare(key_compare __c) : comp(__c) {}
public:
_LIBCPP_INLINE_VISIBILITY
bool operator()(const value_type& __x, const value_type& __y) const
@@ -2000,13 +1998,13 @@ public:
}
template <class _Pp,
- class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+ class = __enable_if_t<is_constructible<value_type, _Pp>::value>>
_LIBCPP_INLINE_VISIBILITY
iterator insert(_Pp&& __p)
{return __tree_.__insert_multi(_VSTD::forward<_Pp>(__p));}
template <class _Pp,
- class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+ class = __enable_if_t<is_constructible<value_type, _Pp>::value>>
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __pos, _Pp&& __p)
{return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));}
@@ -2128,11 +2126,11 @@ public:
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
find(const _K2& __k) {return __tree_.find(__k);}
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, const_iterator>
find(const _K2& __k) const {return __tree_.find(__k);}
#endif
@@ -2142,7 +2140,7 @@ public:
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, size_type>
count(const _K2& __k) const {return __tree_.__count_multi(__k);}
#endif
@@ -2151,7 +2149,7 @@ public:
bool contains(const key_type& __k) const {return find(__k) != end();}
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, bool>
contains(const _K2& __k) const { return find(__k) != end(); }
#endif // _LIBCPP_STD_VER > 17
@@ -2164,12 +2162,12 @@ public:
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);}
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, const_iterator>
lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
#endif
@@ -2182,11 +2180,11 @@ public:
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator>
upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);}
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, const_iterator>
upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
#endif
@@ -2199,11 +2197,11 @@ public:
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, pair<iterator,iterator>>
equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);}
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
+ __enable_if_t<__is_transparent<_Compare, _K2>::value, pair<const_iterator,const_iterator>>
equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
#endif
diff --git a/libcxx/include/memory b/libcxx/include/memory
index 299746022274..ec9f5773929f 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -1096,8 +1096,8 @@ struct __builtin_new_allocator {
_LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align)
: __size_(__size), __align_(__align) {}
- void operator()(void* p) const _NOEXCEPT {
- _VSTD::__libcpp_deallocate(p, __size_, __align_);
+ void operator()(void* __p) const _NOEXCEPT {
+ _VSTD::__libcpp_deallocate(__p, __size_, __align_);
}
private:
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 3e191dc0f86d..25e1c6e6d0e2 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -318,21 +318,31 @@ module std [system] {
module ranges_count { private header "__algorithm/ranges_count.h" }
module ranges_count_if { private header "__algorithm/ranges_count_if.h" }
module ranges_equal { private header "__algorithm/ranges_equal.h" }
+ module ranges_equal_range { private header "__algorithm/ranges_equal_range.h" }
module ranges_fill { private header "__algorithm/ranges_fill.h" }
module ranges_fill_n { private header "__algorithm/ranges_fill_n.h" }
module ranges_find { private header "__algorithm/ranges_find.h" }
+ module ranges_find_end { private header "__algorithm/ranges_find_end.h" }
module ranges_find_first_of { private header "__algorithm/ranges_find_first_of.h" }
module ranges_find_if { private header "__algorithm/ranges_find_if.h" }
module ranges_find_if_not { private header "__algorithm/ranges_find_if_not.h" }
module ranges_for_each { private header "__algorithm/ranges_for_each.h" }
module ranges_for_each_n { private header "__algorithm/ranges_for_each_n.h" }
+ module ranges_generate { private header "__algorithm/ranges_generate.h" }
+ module ranges_generate_n { private header "__algorithm/ranges_generate_n.h" }
+ module ranges_includes { private header "__algorithm/ranges_includes.h" }
+ module ranges_inplace_merge { private header "__algorithm/ranges_inplace_merge.h" }
+ module ranges_is_heap { private header "__algorithm/ranges_is_heap.h" }
+ module ranges_is_heap_until { private header "__algorithm/ranges_is_heap_until.h" }
module ranges_is_partitioned { private header "__algorithm/ranges_is_partitioned.h" }
module ranges_is_sorted { private header "__algorithm/ranges_is_sorted.h" }
module ranges_is_sorted_until { private header "__algorithm/ranges_is_sorted_until.h" }
module ranges_lexicographical_compare { private header "__algorithm/ranges_lexicographical_compare.h" }
module ranges_lower_bound { private header "__algorithm/ranges_lower_bound.h" }
+ module ranges_make_heap { private header "__algorithm/ranges_make_heap.h" }
module ranges_max { private header "__algorithm/ranges_max.h" }
module ranges_max_element { private header "__algorithm/ranges_max_element.h" }
+ module ranges_merge { private header "__algorithm/ranges_merge.h" }
module ranges_min { private header "__algorithm/ranges_min.h" }
module ranges_min_element { private header "__algorithm/ranges_min_element.h" }
module ranges_minmax { private header "__algorithm/ranges_minmax.h" }
@@ -341,13 +351,39 @@ module std [system] {
module ranges_move { private header "__algorithm/ranges_move.h" }
module ranges_move_backward { private header "__algorithm/ranges_move_backward.h" }
module ranges_none_of { private header "__algorithm/ranges_none_of.h" }
+ module ranges_nth_element { private header "__algorithm/ranges_nth_element.h" }
+ module ranges_partial_sort_copy { private header "__algorithm/ranges_partial_sort_copy.h" }
+ module ranges_partition { private header "__algorithm/ranges_partition.h" }
+ module ranges_partition_copy { private header "__algorithm/ranges_partition_copy.h" }
+ module ranges_partition_point { private header "__algorithm/ranges_partition_point.h" }
+ module ranges_pop_heap { private header "__algorithm/ranges_pop_heap.h" }
+ module ranges_push_heap { private header "__algorithm/ranges_push_heap.h" }
+ module ranges_remove { private header "__algorithm/ranges_remove.h" }
+ module ranges_remove_copy { private header "__algorithm/ranges_remove_copy.h" }
+ module ranges_remove_copy_if { private header "__algorithm/ranges_remove_copy_if.h" }
+ module ranges_remove_if { private header "__algorithm/ranges_remove_if.h" }
module ranges_replace { private header "__algorithm/ranges_replace.h" }
+ module ranges_replace_copy { private header "__algorithm/ranges_replace_copy.h" }
+ module ranges_replace_copy_if { private header "__algorithm/ranges_replace_copy_if.h" }
module ranges_replace_if { private header "__algorithm/ranges_replace_if.h" }
module ranges_reverse { private header "__algorithm/ranges_reverse.h" }
+ module ranges_reverse_copy { private header "__algorithm/ranges_reverse_copy.h" }
+ module ranges_rotate_copy { private header "__algorithm/ranges_rotate_copy.h" }
+ module ranges_search { private header "__algorithm/ranges_search.h" }
+ module ranges_search_n { private header "__algorithm/ranges_search_n.h" }
+ module ranges_set_difference { private header "__algorithm/ranges_set_difference.h" }
+ module ranges_set_intersection { private header "__algorithm/ranges_set_intersection.h" }
+ module ranges_set_symmetric_difference { private header "__algorithm/ranges_set_symmetric_difference.h" }
+ module ranges_set_union { private header "__algorithm/ranges_set_union.h" }
+ module ranges_shuffle { private header "__algorithm/ranges_shuffle.h" }
module ranges_sort { private header "__algorithm/ranges_sort.h" }
+ module ranges_sort_heap { private header "__algorithm/ranges_sort_heap.h" }
+ module ranges_stable_partition { private header "__algorithm/ranges_stable_partition.h" }
module ranges_stable_sort { private header "__algorithm/ranges_stable_sort.h" }
module ranges_swap_ranges { private header "__algorithm/ranges_swap_ranges.h" }
module ranges_transform { private header "__algorithm/ranges_transform.h" }
+ module ranges_unique { private header "__algorithm/ranges_unique.h" }
+ module ranges_unique_copy { private header "__algorithm/ranges_unique_copy.h" }
module ranges_upper_bound { private header "__algorithm/ranges_upper_bound.h" }
module remove { private header "__algorithm/remove.h" }
module remove_copy { private header "__algorithm/remove_copy.h" }
@@ -747,6 +783,11 @@ module std [system] {
header "latch"
export *
}
+
+ module __debug_utils {
+ module randomize_range { private header "__debug_utils/randomize_range.h" }
+ }
+
module limits {
header "limits"
export *
diff --git a/libcxx/include/regex b/libcxx/include/regex
index a117c50f3984..850fe099df1e 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -1330,9 +1330,9 @@ regex_traits<_CharT>::isctype(char_type __c, char_class_type __m) const
}
inline _LIBCPP_INLINE_VISIBILITY
-bool __is_07(unsigned char c)
+bool __is_07(unsigned char __c)
{
- return (c & 0xF8u) ==
+ return (__c & 0xF8u) ==
#if defined(__MVS__) && !defined(__NATIVE_ASCII_F)
0xF0;
#else
@@ -1341,9 +1341,9 @@ bool __is_07(unsigned char c)
}
inline _LIBCPP_INLINE_VISIBILITY
-bool __is_89(unsigned char c)
+bool __is_89(unsigned char __c)
{
- return (c & 0xFEu) ==
+ return (__c & 0xFEu) ==
#if defined(__MVS__) && !defined(__NATIVE_ASCII_F)
0xF8;
#else
@@ -1352,12 +1352,12 @@ bool __is_89(unsigned char c)
}
inline _LIBCPP_INLINE_VISIBILITY
-unsigned char __to_lower(unsigned char c)
+unsigned char __to_lower(unsigned char __c)
{
#if defined(__MVS__) && !defined(__NATIVE_ASCII_F)
return c & 0xBF;
#else
- return c | 0x20;
+ return __c | 0x20;
#endif
}
@@ -2057,9 +2057,9 @@ __word_boundary<_CharT, _Traits>::__exec(__state& __s) const
template <class _CharT>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-bool __is_eol(_CharT c)
+bool __is_eol(_CharT __c)
{
- return c == '\r' || c == '\n';
+ return __c == '\r' || __c == '\n';
}
template <class _CharT>
@@ -2748,12 +2748,7 @@ public:
template <class _InputIterator>
_LIBCPP_INLINE_VISIBILITY
- typename enable_if
- <
- __is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value,
- basic_regex&
- >::type
+ typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value, basic_regex&>::type
assign(_InputIterator __first, _InputIterator __last,
flag_type __f = regex_constants::ECMAScript)
{
@@ -2968,7 +2963,7 @@ private:
__parse_awk_escape(_ForwardIterator __first, _ForwardIterator __last,
basic_string<_CharT>* __str = nullptr);
- bool __test_back_ref(_CharT c);
+ bool __test_back_ref(_CharT);
_LIBCPP_INLINE_VISIBILITY
void __push_l_anchor();
@@ -4787,9 +4782,9 @@ basic_regex<_CharT, _Traits>::__parse_egrep(_ForwardIterator __first,
template <class _CharT, class _Traits>
bool
-basic_regex<_CharT, _Traits>::__test_back_ref(_CharT c)
+basic_regex<_CharT, _Traits>::__test_back_ref(_CharT __c)
{
- unsigned __val = __traits_.value(c, 10);
+ unsigned __val = __traits_.value(__c, 10);
if (__val >= 1 && __val <= 9)
{
if (__val > mark_count())
diff --git a/libcxx/include/scoped_allocator b/libcxx/include/scoped_allocator
index b505aad9dcf7..cf82affba78f 100644
--- a/libcxx/include/scoped_allocator
+++ b/libcxx/include/scoped_allocator
@@ -219,10 +219,10 @@ protected:
is_constructible<outer_allocator_type, _OuterA2>::value
>::type>
_LIBCPP_INLINE_VISIBILITY
- __scoped_allocator_storage(_OuterA2&& __outerAlloc,
- const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
- : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)),
- __inner_(__innerAllocs...) {}
+ __scoped_allocator_storage(_OuterA2&& __outer_alloc,
+ const _InnerAllocs& ...__inner_allocs) _NOEXCEPT
+ : outer_allocator_type(_VSTD::forward<_OuterA2>(__outer_alloc)),
+ __inner_(__inner_allocs...) {}
template <class _OuterA2,
class = typename enable_if<
@@ -300,8 +300,8 @@ protected:
is_constructible<outer_allocator_type, _OuterA2>::value
>::type>
_LIBCPP_INLINE_VISIBILITY
- __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT
- : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {}
+ __scoped_allocator_storage(_OuterA2&& __outer_alloc) _NOEXCEPT
+ : outer_allocator_type(_VSTD::forward<_OuterA2>(__outer_alloc)) {}
template <class _OuterA2,
class = typename enable_if<
@@ -444,9 +444,9 @@ public:
is_constructible<outer_allocator_type, _OuterA2>::value
>::type>
_LIBCPP_INLINE_VISIBILITY
- scoped_allocator_adaptor(_OuterA2&& __outerAlloc,
- const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
- : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}
+ scoped_allocator_adaptor(_OuterA2&& __outer_alloc,
+ const _InnerAllocs& ...__inner_allocs) _NOEXCEPT
+ : base(_VSTD::forward<_OuterA2>(__outer_alloc), __inner_allocs...) {}
// scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
template <class _OuterA2,
class = typename enable_if<
diff --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex
index a089aa9fa817..f85cf6ec4c4f 100644
--- a/libcxx/include/shared_mutex
+++ b/libcxx/include/shared_mutex
@@ -400,9 +400,9 @@ public:
void lock();
bool try_lock();
template <class Rep, class Period>
- bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+ bool try_lock_for(const chrono::duration<Rep, Period>& __rel_time);
template <class Clock, class Duration>
- bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& __abs_time);
void unlock();
// Setters
diff --git a/libcxx/include/string_view b/libcxx/include/string_view
index 28013e7cb08e..a84ed5019614 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -324,8 +324,8 @@ public:
ranges::sized_range<_Range> &&
is_same_v<ranges::range_value_t<_Range>, _CharT> &&
!is_convertible_v<_Range, const _CharT*> &&
- (!requires(remove_cvref_t<_Range>& d) {
- d.operator _VSTD::basic_string_view<_CharT, _Traits>();
+ (!requires(remove_cvref_t<_Range>& __d) {
+ __d.operator _VSTD::basic_string_view<_CharT, _Traits>();
}) &&
(!requires {
typename remove_reference_t<_Range>::traits_type;
diff --git a/libcxx/include/system_error b/libcxx/include/system_error
index 2db901847d83..3b705aa81ebc 100644
--- a/libcxx/include/system_error
+++ b/libcxx/include/system_error
@@ -236,7 +236,7 @@ class _LIBCPP_HIDDEN __do_message
: public error_category
{
public:
- virtual string message(int ev) const;
+ virtual string message(int __ev) const;
};
_LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT;
@@ -482,7 +482,7 @@ private:
};
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS
-void __throw_system_error(int ev, const char* what_arg);
+void __throw_system_error(int __ev, const char* __what_arg);
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index 221eb23dd3f8..79527cca5853 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -482,10 +482,7 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
{}
template <class _Tuple,
- class = typename enable_if
- <
- __tuple_constructible<_Tuple, tuple<_Tp...> >::value
- >::type
+ class = __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value>
>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
__tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
@@ -495,10 +492,7 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
{}
template <class _Alloc, class _Tuple,
- class = typename enable_if
- <
- __tuple_constructible<_Tuple, tuple<_Tp...> >::value
- >::type
+ class = __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value>
>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
__tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
@@ -1336,11 +1330,7 @@ tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
template <class ..._Tp>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-typename enable_if
-<
- __all<__is_swappable<_Tp>::value...>::value,
- void
->::type
+__enable_if_t<__all<__is_swappable<_Tp>::value...>::value, void>
swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
_NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
{__t.swap(__u);}
diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map
index 72749e11e843..b2a12cb638d8 100644
--- a/libcxx/include/unordered_map
+++ b/libcxx/include/unordered_map
@@ -876,9 +876,7 @@ public:
}
template <class _ValueTp,
- class = typename enable_if<
- __is_same_uncvref<_ValueTp, value_type>::value
- >::type
+ class = __enable_if_t<__is_same_uncvref<_ValueTp, value_type>::value>
>
_LIBCPP_INLINE_VISIBILITY
__hash_value_type& operator=(_ValueTp&& __v)
@@ -1237,13 +1235,13 @@ public:
}
template <class _Pp,
- class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+ class = __enable_if_t<is_constructible<value_type, _Pp>::value> >
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> insert(_Pp&& __x)
{return __table_.__insert_unique(_VSTD::forward<_Pp>(__x));}
template <class _Pp,
- class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+ class = __enable_if_t<is_constructible<value_type, _Pp>::value> >
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __p, _Pp&& __x)
{
@@ -1527,9 +1525,9 @@ public:
_LIBCPP_INLINE_VISIBILITY
void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
_LIBCPP_INLINE_VISIBILITY
- void rehash(size_type __n) {__table_.rehash(__n);}
+ void rehash(size_type __n) {__table_.__rehash_unique(__n);}
_LIBCPP_INLINE_VISIBILITY
- void reserve(size_type __n) {__table_.reserve(__n);}
+ void reserve(size_type __n) {__table_.__reserve_unique(__n);}
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
@@ -1628,7 +1626,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
: __table_(__hf, __eql)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -1638,7 +1636,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
: __table_(__hf, __eql, typename __table::allocator_type(__a))
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -1667,7 +1665,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
: __table_(__hf, __eql)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
insert(__first, __last);
}
@@ -1679,7 +1677,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
: __table_(__hf, __eql, typename __table::allocator_type(__a))
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
insert(__first, __last);
}
@@ -1689,7 +1687,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
: __table_(__u.__table_)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__u.bucket_count());
+ __table_.__rehash_unique(__u.bucket_count());
insert(__u.begin(), __u.end());
}
@@ -1699,7 +1697,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
: __table_(__u.__table_, typename __table::allocator_type(__a))
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__u.bucket_count());
+ __table_.__rehash_unique(__u.bucket_count());
insert(__u.begin(), __u.end());
}
@@ -1749,7 +1747,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
: __table_(__hf, __eql)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
insert(__il.begin(), __il.end());
}
@@ -1760,7 +1758,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
: __table_(__hf, __eql, typename __table::allocator_type(__a))
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
insert(__il.begin(), __il.end());
}
@@ -2114,13 +2112,13 @@ public:
{return __table_.__insert_multi(__p.__i_, _VSTD::move(__x));}
template <class _Pp,
- class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+ class = __enable_if_t<is_constructible<value_type, _Pp>::value> >
_LIBCPP_INLINE_VISIBILITY
iterator insert(_Pp&& __x)
{return __table_.__insert_multi(_VSTD::forward<_Pp>(__x));}
template <class _Pp,
- class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+ class = __enable_if_t<is_constructible<value_type, _Pp>::value> >
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __p, _Pp&& __x)
{return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));}
@@ -2303,9 +2301,9 @@ public:
_LIBCPP_INLINE_VISIBILITY
void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
_LIBCPP_INLINE_VISIBILITY
- void rehash(size_type __n) {__table_.rehash(__n);}
+ void rehash(size_type __n) {__table_.__rehash_multi(__n);}
_LIBCPP_INLINE_VISIBILITY
- void reserve(size_type __n) {__table_.reserve(__n);}
+ void reserve(size_type __n) {__table_.__reserve_multi(__n);}
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
@@ -2400,7 +2398,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
: __table_(__hf, __eql)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -2410,7 +2408,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
: __table_(__hf, __eql, typename __table::allocator_type(__a))
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -2430,7 +2428,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
: __table_(__hf, __eql)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
insert(__first, __last);
}
@@ -2442,7 +2440,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
: __table_(__hf, __eql, typename __table::allocator_type(__a))
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
insert(__first, __last);
}
@@ -2461,7 +2459,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
: __table_(__u.__table_)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__u.bucket_count());
+ __table_.__rehash_multi(__u.bucket_count());
insert(__u.begin(), __u.end());
}
@@ -2471,7 +2469,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
: __table_(__u.__table_, typename __table::allocator_type(__a))
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__u.bucket_count());
+ __table_.__rehash_multi(__u.bucket_count());
insert(__u.begin(), __u.end());
}
@@ -2522,7 +2520,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
: __table_(__hf, __eql)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
insert(__il.begin(), __il.end());
}
@@ -2533,7 +2531,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
: __table_(__hf, __eql, typename __table::allocator_type(__a))
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
insert(__il.begin(), __il.end());
}
diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set
index 97aa935f187c..fc6e8e21c0cb 100644
--- a/libcxx/include/unordered_set
+++ b/libcxx/include/unordered_set
@@ -858,9 +858,9 @@ public:
_LIBCPP_INLINE_VISIBILITY
void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
_LIBCPP_INLINE_VISIBILITY
- void rehash(size_type __n) {__table_.rehash(__n);}
+ void rehash(size_type __n) {__table_.__rehash_unique(__n);}
_LIBCPP_INLINE_VISIBILITY
- void reserve(size_type __n) {__table_.reserve(__n);}
+ void reserve(size_type __n) {__table_.__reserve_unique(__n);}
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
@@ -942,7 +942,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,
: __table_(__hf, __eql)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
}
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -951,7 +951,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,
: __table_(__hf, __eql, __a)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
}
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -971,7 +971,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
: __table_(__hf, __eql)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
insert(__first, __last);
}
@@ -983,7 +983,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
: __table_(__hf, __eql, __a)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
insert(__first, __last);
}
@@ -1002,7 +1002,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
: __table_(__u.__table_)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__u.bucket_count());
+ __table_.__rehash_unique(__u.bucket_count());
insert(__u.begin(), __u.end());
}
@@ -1012,7 +1012,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
: __table_(__u.__table_, __a)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__u.bucket_count());
+ __table_.__rehash_unique(__u.bucket_count());
insert(__u.begin(), __u.end());
}
@@ -1060,7 +1060,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
: __table_(__hf, __eql)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
insert(__il.begin(), __il.end());
}
@@ -1071,7 +1071,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
: __table_(__hf, __eql, __a)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_unique(__n);
insert(__il.begin(), __il.end());
}
@@ -1496,9 +1496,9 @@ public:
_LIBCPP_INLINE_VISIBILITY
void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
_LIBCPP_INLINE_VISIBILITY
- void rehash(size_type __n) {__table_.rehash(__n);}
+ void rehash(size_type __n) {__table_.__rehash_multi(__n);}
_LIBCPP_INLINE_VISIBILITY
- void reserve(size_type __n) {__table_.reserve(__n);}
+ void reserve(size_type __n) {__table_.__reserve_multi(__n);}
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
@@ -1578,7 +1578,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
: __table_(__hf, __eql)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
}
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -1588,7 +1588,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
: __table_(__hf, __eql, __a)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
}
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -1608,7 +1608,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
: __table_(__hf, __eql)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
insert(__first, __last);
}
@@ -1620,7 +1620,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
: __table_(__hf, __eql, __a)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
insert(__first, __last);
}
@@ -1639,7 +1639,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
: __table_(__u.__table_)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__u.bucket_count());
+ __table_.__rehash_multi(__u.bucket_count());
insert(__u.begin(), __u.end());
}
@@ -1649,7 +1649,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
: __table_(__u.__table_, __a)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__u.bucket_count());
+ __table_.__rehash_multi(__u.bucket_count());
insert(__u.begin(), __u.end());
}
@@ -1697,7 +1697,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
: __table_(__hf, __eql)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
insert(__il.begin(), __il.end());
}
@@ -1708,7 +1708,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
: __table_(__hf, __eql, __a)
{
_VSTD::__debug_db_insert_c(this);
- __table_.rehash(__n);
+ __table_.__rehash_multi(__n);
insert(__il.begin(), __il.end());
}
diff --git a/libcxx/include/variant b/libcxx/include/variant
index 65dec64dbbbd..b74416b62d91 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -777,8 +777,8 @@ public:
using __index_t = __variant_index_t<sizeof...(_Types)>;
inline _LIBCPP_INLINE_VISIBILITY
- explicit constexpr __base(__valueless_t tag) noexcept
- : __data(tag), __index(__variant_npos<__index_t>) {}
+ explicit constexpr __base(__valueless_t __tag) noexcept
+ : __data(__tag), __index(__variant_npos<__index_t>) {}
template <size_t _Ip, class... _Args>
inline _LIBCPP_INLINE_VISIBILITY
diff --git a/libcxx/include/vector b/libcxx/include/vector
index f5c09011948d..14f586c9bfd7 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -393,16 +393,14 @@ public:
template <class _InputIterator>
vector(_InputIterator __first,
- typename enable_if<__is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value &&
+ typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
is_constructible<
value_type,
typename iterator_traits<_InputIterator>::reference>::value,
_InputIterator>::type __last);
template <class _InputIterator>
vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
- typename enable_if<__is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value &&
+ typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
is_constructible<
value_type,
typename iterator_traits<_InputIterator>::reference>::value>::type* = 0);
@@ -465,10 +463,7 @@ public:
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
template <class _InputIterator>
- typename enable_if
- <
- __is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value &&
+ typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
is_constructible<
value_type,
typename iterator_traits<_InputIterator>::reference>::value,
@@ -598,10 +593,7 @@ public:
iterator insert(const_iterator __position, size_type __n, const_reference __x);
template <class _InputIterator>
- typename enable_if
- <
- __is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value &&
+ typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
is_constructible<
value_type,
typename iterator_traits<_InputIterator>::reference>::value,
@@ -1090,8 +1082,7 @@ vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x)
template <class _Tp, class _Allocator>
template <class _InputIterator>
vector<_Tp, _Allocator>::vector(_InputIterator __first,
- typename enable_if<__is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value &&
+ typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
is_constructible<
value_type,
typename iterator_traits<_InputIterator>::reference>::value,
@@ -1105,8 +1096,7 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first,
template <class _Tp, class _Allocator>
template <class _InputIterator>
vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
- typename enable_if<__is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value &&
+ typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
is_constructible<
value_type,
typename iterator_traits<_InputIterator>::reference>::value>::type*)
@@ -1301,10 +1291,7 @@ vector<_Tp, _Allocator>::operator=(const vector& __x)
template <class _Tp, class _Allocator>
template <class _InputIterator>
-typename enable_if
-<
- __is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value &&
+typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
is_constructible<
_Tp,
typename iterator_traits<_InputIterator>::reference>::value,
@@ -1751,10 +1738,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_
template <class _Tp, class _Allocator>
template <class _InputIterator>
-typename enable_if
-<
- __is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value &&
+typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
is_constructible<
_Tp,
typename iterator_traits<_InputIterator>::reference>::value,
@@ -2057,12 +2041,10 @@ public:
vector(size_type __n, const value_type& __v, const allocator_type& __a);
template <class _InputIterator>
vector(_InputIterator __first, _InputIterator __last,
- typename enable_if<__is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value>::type* = 0);
+ typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type* = 0);
template <class _InputIterator>
vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
- typename enable_if<__is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value>::type* = 0);
+ typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type* = 0);
template <class _ForwardIterator>
vector(_ForwardIterator __first, _ForwardIterator __last,
typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0);
@@ -2097,10 +2079,7 @@ public:
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
template <class _InputIterator>
- typename enable_if
- <
- __is_cpp17_input_iterator<_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value,
+ typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
void
>::type
assign(_InputIterator __first, _InputIterator __last);
@@ -2205,17 +2184,14 @@ public:
#if _LIBCPP_STD_VER > 11
template <class... _Args>
- _LIBCPP_INLINE_VISIBILITY iterator emplace(const_iterator position, _Args&&... __args)
- { return insert ( position, value_type ( _VSTD::forward<_Args>(__args)... )); }
+ _LIBCPP_INLINE_VISIBILITY iterator emplace(const_iterator __position, _Args&&... __args)
+ { return insert ( __position, value_type ( _VSTD::forward<_Args>(__args)... )); }
#endif
iterator insert(const_iterator __position, const value_type& __x);
iterator insert(const_iterator __position, size_type __n, const value_type& __x);
template <class _InputIterator>
- typename enable_if
- <
- __is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value,
+ typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
iterator
>::type
insert(const_iterator __position, _InputIterator __first, _InputIterator __last);
@@ -2522,8 +2498,7 @@ vector<bool, _Allocator>::vector(size_type __n, const value_type& __x, const all
template <class _Allocator>
template <class _InputIterator>
vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
- typename enable_if<__is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value>::type*)
+ typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type*)
: __begin_(nullptr),
__size_(0),
__cap_alloc_(0, __default_init_tag())
@@ -2549,8 +2524,7 @@ vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
template <class _Allocator>
template <class _InputIterator>
vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
- typename enable_if<__is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value>::type*)
+ typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type*)
: __begin_(nullptr),
__size_(0),
__cap_alloc_(0, static_cast<__storage_allocator>(__a))
@@ -2787,10 +2761,7 @@ vector<bool, _Allocator>::assign(size_type __n, const value_type& __x)
template <class _Allocator>
template <class _InputIterator>
-typename enable_if
-<
- __is_cpp17_input_iterator<_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value,
+typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
void
>::type
vector<bool, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
@@ -2941,10 +2912,7 @@ vector<bool, _Allocator>::insert(const_iterator __position, size_type __n, const
template <class _Allocator>
template <class _InputIterator>
-typename enable_if
-<
- __is_cpp17_input_iterator <_InputIterator>::value &&
- !__is_cpp17_forward_iterator<_InputIterator>::value,
+typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
typename vector<bool, _Allocator>::iterator
>::type
vector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)
diff --git a/libcxx/include/wchar.h b/libcxx/include/wchar.h
index ce63cf247618..0fba53b268ae 100644
--- a/libcxx/include/wchar.h
+++ b/libcxx/include/wchar.h
@@ -176,10 +176,10 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD
#if defined(__cplusplus) && (defined(_LIBCPP_MSVCRT_LIKE) || defined(__MVS__))
extern "C" {
-size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,
- size_t nmc, size_t len, mbstate_t *__restrict ps);
-size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src,
- size_t nwc, size_t len, mbstate_t *__restrict ps);
+size_t mbsnrtowcs(wchar_t *__restrict __dst, const char **__restrict __src,
+ size_t __nmc, size_t __len, mbstate_t *__restrict __ps);
+size_t wcsnrtombs(char *__restrict __dst, const wchar_t **__restrict __src,
+ size_t __nwc, size_t __len, mbstate_t *__restrict __ps);
} // extern "C"
#endif // __cplusplus && (_LIBCPP_MSVCRT || __MVS__)