[libc++] Format the code base (#74334)

This patch runs clang-format on all of libcxx/include and libcxx/src, in
accordance with the RFC discussed at [1]. Follow-up patches will format
the benchmarks, the test suite and remaining parts of the code. I'm
splitting this one into its own patch so the diff is a bit easier to
review.

This patch was generated with:

   find libcxx/include libcxx/src -type f \
      | grep -v 'module.modulemap.in' \
      | grep -v 'CMakeLists.txt' \
      | grep -v 'README.txt' \
      | grep -v 'libcxx.imp' \
      | grep -v '__config_site.in' \
      | xargs clang-format -i

A Git merge driver is available in libcxx/utils/clang-format-merge-driver.sh
to help resolve merge and rebase issues across these formatting changes.

[1]: https://discourse.llvm.org/t/rfc-clang-formatting-all-of-libc-once-and-for-all
This commit is contained in:
Louis Dionne 2023-12-18 14:01:33 -05:00 committed by GitHub
parent e5c523e861
commit 9783f28cbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
542 changed files with 66602 additions and 83948 deletions

142
.gitattributes vendored Normal file
View File

@ -0,0 +1,142 @@
libcxx/src/**/*.cpp merge=libcxx-reformat
libcxx/include/**/*.h merge=libcxx-reformat
# Explicitly handle files with no extension
libcxx/include/__availability merge=libcxx-reformat
libcxx/include/__bit_reference merge=libcxx-reformat
libcxx/include/__config merge=libcxx-reformat
libcxx/include/__hash_table merge=libcxx-reformat
libcxx/include/__locale merge=libcxx-reformat
libcxx/include/__node_handle merge=libcxx-reformat
libcxx/include/__split_buffer merge=libcxx-reformat
libcxx/include/__std_clang_module merge=libcxx-reformat
libcxx/include/__threading_support merge=libcxx-reformat
libcxx/include/__tree merge=libcxx-reformat
libcxx/include/__verbose_abort merge=libcxx-reformat
libcxx/include/algorithm merge=libcxx-reformat
libcxx/include/any merge=libcxx-reformat
libcxx/include/array merge=libcxx-reformat
libcxx/include/atomic merge=libcxx-reformat
libcxx/include/barrier merge=libcxx-reformat
libcxx/include/bit merge=libcxx-reformat
libcxx/include/bitset merge=libcxx-reformat
libcxx/include/cassert merge=libcxx-reformat
libcxx/include/ccomplex merge=libcxx-reformat
libcxx/include/cctype merge=libcxx-reformat
libcxx/include/cerrno merge=libcxx-reformat
libcxx/include/cfenv merge=libcxx-reformat
libcxx/include/cfloat merge=libcxx-reformat
libcxx/include/charconv merge=libcxx-reformat
libcxx/include/chrono merge=libcxx-reformat
libcxx/include/cinttypes merge=libcxx-reformat
libcxx/include/ciso646 merge=libcxx-reformat
libcxx/include/climits merge=libcxx-reformat
libcxx/include/clocale merge=libcxx-reformat
libcxx/include/cmath merge=libcxx-reformat
libcxx/include/codecvt merge=libcxx-reformat
libcxx/include/compare merge=libcxx-reformat
libcxx/include/complex merge=libcxx-reformat
libcxx/include/concepts merge=libcxx-reformat
libcxx/include/condition_variable merge=libcxx-reformat
libcxx/include/coroutine merge=libcxx-reformat
libcxx/include/csetjmp merge=libcxx-reformat
libcxx/include/csignal merge=libcxx-reformat
libcxx/include/cstdarg merge=libcxx-reformat
libcxx/include/cstdbool merge=libcxx-reformat
libcxx/include/cstddef merge=libcxx-reformat
libcxx/include/cstdint merge=libcxx-reformat
libcxx/include/cstdio merge=libcxx-reformat
libcxx/include/cstdlib merge=libcxx-reformat
libcxx/include/cstring merge=libcxx-reformat
libcxx/include/ctgmath merge=libcxx-reformat
libcxx/include/ctime merge=libcxx-reformat
libcxx/include/cuchar merge=libcxx-reformat
libcxx/include/cwchar merge=libcxx-reformat
libcxx/include/cwctype merge=libcxx-reformat
libcxx/include/deque merge=libcxx-reformat
libcxx/include/exception merge=libcxx-reformat
libcxx/include/execution merge=libcxx-reformat
libcxx/include/expected merge=libcxx-reformat
libcxx/include/experimental/__config merge=libcxx-reformat
libcxx/include/experimental/__memory merge=libcxx-reformat
libcxx/include/experimental/deque merge=libcxx-reformat
libcxx/include/experimental/forward_list merge=libcxx-reformat
libcxx/include/experimental/iterator merge=libcxx-reformat
libcxx/include/experimental/list merge=libcxx-reformat
libcxx/include/experimental/map merge=libcxx-reformat
libcxx/include/experimental/memory merge=libcxx-reformat
libcxx/include/experimental/memory_resource merge=libcxx-reformat
libcxx/include/experimental/propagate_const merge=libcxx-reformat
libcxx/include/experimental/regex merge=libcxx-reformat
libcxx/include/experimental/set merge=libcxx-reformat
libcxx/include/experimental/simd merge=libcxx-reformat
libcxx/include/experimental/string merge=libcxx-reformat
libcxx/include/experimental/type_traits merge=libcxx-reformat
libcxx/include/experimental/unordered_map merge=libcxx-reformat
libcxx/include/experimental/unordered_set merge=libcxx-reformat
libcxx/include/experimental/utility merge=libcxx-reformat
libcxx/include/experimental/vector merge=libcxx-reformat
libcxx/include/ext/__hash merge=libcxx-reformat
libcxx/include/ext/hash_map merge=libcxx-reformat
libcxx/include/ext/hash_set merge=libcxx-reformat
libcxx/include/filesystem merge=libcxx-reformat
libcxx/include/format merge=libcxx-reformat
libcxx/include/forward_list merge=libcxx-reformat
libcxx/include/fstream merge=libcxx-reformat
libcxx/include/functional merge=libcxx-reformat
libcxx/include/future merge=libcxx-reformat
libcxx/include/initializer_list merge=libcxx-reformat
libcxx/include/iomanip merge=libcxx-reformat
libcxx/include/ios merge=libcxx-reformat
libcxx/include/iosfwd merge=libcxx-reformat
libcxx/include/iostream merge=libcxx-reformat
libcxx/include/istream merge=libcxx-reformat
libcxx/include/iterator merge=libcxx-reformat
libcxx/include/latch merge=libcxx-reformat
libcxx/include/limits merge=libcxx-reformat
libcxx/include/list merge=libcxx-reformat
libcxx/include/locale merge=libcxx-reformat
libcxx/include/map merge=libcxx-reformat
libcxx/include/mdspan merge=libcxx-reformat
libcxx/include/memory merge=libcxx-reformat
libcxx/include/memory_resource merge=libcxx-reformat
libcxx/include/mutex merge=libcxx-reformat
libcxx/include/new merge=libcxx-reformat
libcxx/include/numbers merge=libcxx-reformat
libcxx/include/numeric merge=libcxx-reformat
libcxx/include/optional merge=libcxx-reformat
libcxx/include/ostream merge=libcxx-reformat
libcxx/include/print merge=libcxx-reformat
libcxx/include/queue merge=libcxx-reformat
libcxx/include/random merge=libcxx-reformat
libcxx/include/ranges merge=libcxx-reformat
libcxx/include/ratio merge=libcxx-reformat
libcxx/include/regex merge=libcxx-reformat
libcxx/include/scoped_allocator merge=libcxx-reformat
libcxx/include/semaphore merge=libcxx-reformat
libcxx/include/set merge=libcxx-reformat
libcxx/include/shared_mutex merge=libcxx-reformat
libcxx/include/source_location merge=libcxx-reformat
libcxx/include/span merge=libcxx-reformat
libcxx/include/sstream merge=libcxx-reformat
libcxx/include/stack merge=libcxx-reformat
libcxx/include/stdexcept merge=libcxx-reformat
libcxx/include/stop_token merge=libcxx-reformat
libcxx/include/streambuf merge=libcxx-reformat
libcxx/include/string merge=libcxx-reformat
libcxx/include/string_view merge=libcxx-reformat
libcxx/include/strstream merge=libcxx-reformat
libcxx/include/syncstream merge=libcxx-reformat
libcxx/include/system_error merge=libcxx-reformat
libcxx/include/thread merge=libcxx-reformat
libcxx/include/tuple merge=libcxx-reformat
libcxx/include/type_traits merge=libcxx-reformat
libcxx/include/typeindex merge=libcxx-reformat
libcxx/include/typeinfo merge=libcxx-reformat
libcxx/include/unordered_map merge=libcxx-reformat
libcxx/include/unordered_set merge=libcxx-reformat
libcxx/include/utility merge=libcxx-reformat
libcxx/include/valarray merge=libcxx-reformat
libcxx/include/variant merge=libcxx-reformat
libcxx/include/vector merge=libcxx-reformat
libcxx/include/version merge=libcxx-reformat

View File

@ -22,22 +22,16 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator, class _Tp, class _Compare> template <class _ForwardIterator, class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) {
bool __first = std::lower_bound<_ForwardIterator, _Tp, __comp_ref_type<_Compare> >(__first, __last, __value, __comp);
binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) return __first != __last && !__comp(__value, *__first);
{
__first = std::lower_bound<_ForwardIterator, _Tp, __comp_ref_type<_Compare> >(__first, __last, __value, __comp);
return __first != __last && !__comp(__value, *__first);
} }
template <class _ForwardIterator, class _Tp> template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
bool return std::binary_search(__first, __last, __value, __less<>());
binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
{
return std::binary_search(__first, __last, __value, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -20,52 +20,42 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Compare> template <class _Compare>
struct __debug_less struct __debug_less {
{ _Compare& __comp_;
_Compare &__comp_; _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI __debug_less(_Compare& __c) : __comp_(__c) {}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI __debug_less(_Compare& __c) : __comp_(__c) {}
template <class _Tp, class _Up> template <class _Tp, class _Up>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Up& __y) {
bool operator()(const _Tp& __x, const _Up& __y) bool __r = __comp_(__x, __y);
{ if (__r)
bool __r = __comp_(__x, __y); __do_compare_assert(0, __y, __x);
if (__r) return __r;
__do_compare_assert(0, __y, __x); }
return __r;
}
template <class _Tp, class _Up> template <class _Tp, class _Up>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(_Tp& __x, _Up& __y) {
bool operator()(_Tp& __x, _Up& __y) bool __r = __comp_(__x, __y);
{ if (__r)
bool __r = __comp_(__x, __y); __do_compare_assert(0, __y, __x);
if (__r) return __r;
__do_compare_assert(0, __y, __x); }
return __r;
}
template <class _LHS, class _RHS> template <class _LHS, class _RHS>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI decltype((void)std::declval<_Compare&>()(
inline _LIBCPP_HIDE_FROM_ABI std::declval<_LHS&>(), std::declval<_RHS&>()))
decltype((void)std::declval<_Compare&>()( __do_compare_assert(int, _LHS& __l, _RHS& __r) {
std::declval<_LHS &>(), std::declval<_RHS &>())) _LIBCPP_ASSERT_UNCATEGORIZED(!__comp_(__l, __r), "Comparator does not induce a strict weak ordering");
__do_compare_assert(int, _LHS & __l, _RHS & __r) { (void)__l;
_LIBCPP_ASSERT_UNCATEGORIZED(!__comp_(__l, __r), (void)__r;
"Comparator does not induce a strict weak ordering"); }
(void)__l;
(void)__r;
}
template <class _LHS, class _RHS> template <class _LHS, class _RHS>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI void __do_compare_assert(long, _LHS&, _RHS&) {}
inline _LIBCPP_HIDE_FROM_ABI
void __do_compare_assert(long, _LHS &, _RHS &) {}
}; };
// Pass the comparator by lvalue reference. Or in debug mode, using a // Pass the comparator by lvalue reference. Or in debug mode, using a
// debugging wrapper that stores a reference. // debugging wrapper that stores a reference.
# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG #if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
template <class _Comp> template <class _Comp>
using __comp_ref_type = __debug_less<_Comp>; using __comp_ref_type = __debug_less<_Comp>;
#else #else

View File

@ -108,8 +108,7 @@ struct __copy_backward_loop {
struct __copy_backward_trivial { struct __copy_backward_trivial {
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
template <class _In, class _Out, template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
__enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
operator()(_In* __first, _In* __last, _Out* __result) const { operator()(_In* __first, _In* __last, _Out* __result) const {
return std::__copy_backward_trivial_impl(__first, __last, __result); return std::__copy_backward_trivial_impl(__first, __last, __result);
@ -124,16 +123,13 @@ __copy_backward(_BidirectionalIterator1 __first, _Sentinel __last, _Bidirectiona
} }
template <class _BidirectionalIterator1, class _BidirectionalIterator2> template <class _BidirectionalIterator1, class _BidirectionalIterator2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2
_BidirectionalIterator2 copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) {
copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
_BidirectionalIterator2 __result)
{
static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value && static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value &&
std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible."); std::is_copy_constructible<_BidirectionalIterator1>::value,
"Iterators must be copy constructible.");
return std::__copy_backward<_ClassicAlgPolicy>( return std::__copy_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second;
std::move(__first), std::move(__last), std::move(__result)).second;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -17,21 +17,16 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template<class _InputIterator, class _OutputIterator, class _Predicate> template <class _InputIterator, class _OutputIterator, class _Predicate>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
_OutputIterator copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) {
copy_if(_InputIterator __first, _InputIterator __last, for (; __first != __last; ++__first) {
_OutputIterator __result, _Predicate __pred) if (__pred(*__first)) {
{ *__result = *__first;
for (; __first != __last; ++__first) ++__result;
{
if (__pred(*__first))
{
*__result = *__first;
++__result;
}
} }
return __result; }
return __result;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -38,22 +38,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _From, class _To> template <class _From, class _To>
struct __can_lower_copy_assignment_to_memmove { struct __can_lower_copy_assignment_to_memmove {
static const bool value = static const bool value =
// If the types are always bitcastable, it's valid to do a bitwise copy between them. // If the types are always bitcastable, it's valid to do a bitwise copy between them.
__is_always_bitcastable<_From, _To>::value && __is_always_bitcastable<_From, _To>::value &&
// Reject conversions that wouldn't be performed by the regular built-in assignment (e.g. between arrays). // Reject conversions that wouldn't be performed by the regular built-in assignment (e.g. between arrays).
is_trivially_assignable<_To&, const _From&>::value && is_trivially_assignable<_To&, const _From&>::value &&
// `memmove` doesn't accept `volatile` pointers, make sure the optimization SFINAEs away in that case. // `memmove` doesn't accept `volatile` pointers, make sure the optimization SFINAEs away in that case.
!is_volatile<_From>::value && !is_volatile<_From>::value && !is_volatile<_To>::value;
!is_volatile<_To>::value;
}; };
template <class _From, class _To> template <class _From, class _To>
struct __can_lower_move_assignment_to_memmove { struct __can_lower_move_assignment_to_memmove {
static const bool value = static const bool value =
__is_always_bitcastable<_From, _To>::value && __is_always_bitcastable<_From, _To>::value && is_trivially_assignable<_To&, _From&&>::value &&
is_trivially_assignable<_To&, _From&&>::value && !is_volatile<_From>::value && !is_volatile<_To>::value;
!is_volatile<_From>::value &&
!is_volatile<_To>::value;
}; };
// `memmove` algorithms implementation. // `memmove` algorithms implementation.
@ -95,8 +92,8 @@ struct __can_rewrap<_InIter,
_Sent, _Sent,
_OutIter, _OutIter,
// Note that sentinels are always copy-constructible. // Note that sentinels are always copy-constructible.
__enable_if_t< is_copy_constructible<_InIter>::value && __enable_if_t< is_copy_constructible<_InIter>::value && is_copy_constructible<_OutIter>::value > >
is_copy_constructible<_OutIter>::value > > : true_type {}; : true_type {};
template <class _Algorithm, template <class _Algorithm,
class _InIter, class _InIter,
@ -108,7 +105,7 @@ __unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) {
auto __range = std::__unwrap_range(__first, std::move(__last)); auto __range = std::__unwrap_range(__first, std::move(__last));
auto __result = _Algorithm()(std::move(__range.first), std::move(__range.second), std::__unwrap_iter(__out_first)); auto __result = _Algorithm()(std::move(__range.first), std::move(__range.second), std::__unwrap_iter(__out_first));
return std::make_pair(std::__rewrap_range<_Sent>(std::move(__first), std::move(__result.first)), return std::make_pair(std::__rewrap_range<_Sent>(std::move(__first), std::move(__result.first)),
std::__rewrap_iter(std::move(__out_first), std::move(__result.second))); std::__rewrap_iter(std::move(__out_first), std::move(__result.second)));
} }
template <class _Algorithm, template <class _Algorithm,

View File

@ -21,39 +21,38 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template<class _InputIterator, class _Size, class _OutputIterator, template <class _InputIterator,
__enable_if_t<__has_input_iterator_category<_InputIterator>::value && class _Size,
!__has_random_access_iterator_category<_InputIterator>::value, int> = 0> class _OutputIterator,
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__has_input_iterator_category<_InputIterator>::value &&
_OutputIterator !__has_random_access_iterator_category<_InputIterator>::value,
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) int> = 0>
{ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
_IntegralSize __n = __orig_n; typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
if (__n > 0) _IntegralSize __n = __orig_n;
{ if (__n > 0) {
*__result = *__first; *__result = *__first;
++__result; ++__result;
for (--__n; __n > 0; --__n) for (--__n; __n > 0; --__n) {
{ ++__first;
++__first; *__result = *__first;
*__result = *__first; ++__result;
++__result;
}
} }
return __result; }
return __result;
} }
template<class _InputIterator, class _Size, class _OutputIterator, template <class _InputIterator,
__enable_if_t<__has_random_access_iterator_category<_InputIterator>::value, int> = 0> class _Size,
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 class _OutputIterator,
_OutputIterator __enable_if_t<__has_random_access_iterator_category<_InputIterator>::value, int> = 0>
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
{ copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
typedef typename iterator_traits<_InputIterator>::difference_type difference_type; typedef typename iterator_traits<_InputIterator>::difference_type difference_type;
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
_IntegralSize __n = __orig_n; _IntegralSize __n = __orig_n;
return std::copy(__first, __first + difference_type(__n), __result); return std::copy(__first, __first + difference_type(__n), __result);
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -68,8 +68,13 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first
#if _LIBCPP_STD_VER >= 14 #if _LIBCPP_STD_VER >= 14
template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2> template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
__equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, __equal(_InputIterator1 __first1,
_BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) { _InputIterator1 __last1,
_InputIterator2 __first2,
_InputIterator2 __last2,
_BinaryPredicate __pred,
input_iterator_tag,
input_iterator_tag) {
for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
if (!__pred(*__first1, *__first2)) if (!__pred(*__first1, *__first2))
return false; return false;
@ -104,8 +109,12 @@ __equal_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&,
template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, __equal(_RandomAccessIterator1 __first1,
_RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, _RandomAccessIterator1 __last1,
_RandomAccessIterator2 __first2,
_RandomAccessIterator2 __last2,
_BinaryPredicate __pred,
random_access_iterator_tag,
random_access_iterator_tag) { random_access_iterator_tag) {
if (std::distance(__first1, __last1) != std::distance(__first2, __last2)) if (std::distance(__first1, __last1) != std::distance(__first2, __last2))
return false; return false;
@ -122,10 +131,18 @@ __equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _Random
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, equal(_InputIterator1 __first1,
_InputIterator1 __last1,
_InputIterator2 __first2,
_InputIterator2 __last2,
_BinaryPredicate __pred) { _BinaryPredicate __pred) {
return std::__equal<_BinaryPredicate&>( return std::__equal<_BinaryPredicate&>(
__first1, __last1, __first2, __last2, __pred, typename iterator_traits<_InputIterator1>::iterator_category(), __first1,
__last1,
__first2,
__last2,
__pred,
typename iterator_traits<_InputIterator1>::iterator_category(),
typename iterator_traits<_InputIterator2>::iterator_category()); typename iterator_traits<_InputIterator2>::iterator_category());
} }

View File

@ -49,9 +49,8 @@ __equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp
__len = __half_len; __len = __half_len;
} else { } else {
_Iter __mp1 = __mid; _Iter __mp1 = __mid;
return pair<_Iter, _Iter>( return pair<_Iter, _Iter>(std::__lower_bound<_AlgPolicy>(__first, __mid, __value, __comp, __proj),
std::__lower_bound<_AlgPolicy>(__first, __mid, __value, __comp, __proj), std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj));
std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj));
} }
} }
return pair<_Iter, _Iter>(__first, __first); return pair<_Iter, _Iter>(__first, __first);
@ -60,10 +59,8 @@ __equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp
template <class _ForwardIterator, class _Tp, class _Compare> template <class _ForwardIterator, class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 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) {
static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable");
"The comparator has to be callable"); static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible");
static_assert(is_copy_constructible<_ForwardIterator>::value,
"Iterator has to be copy constructible");
return std::__equal_range<_ClassicAlgPolicy>( return std::__equal_range<_ClassicAlgPolicy>(
std::move(__first), std::move(__first),
std::move(__last), std::move(__last),

View File

@ -22,28 +22,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset. // fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
template <class _ForwardIterator, class _Tp> template <class _ForwardIterator, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
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;
for (; __first != __last; ++__first)
*__first = __value;
} }
template <class _RandomAccessIterator, class _Tp> template <class _RandomAccessIterator, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
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) std::fill_n(__first, __last - __first, __value);
{
std::fill_n(__first, __last - __first, __value);
} }
template <class _ForwardIterator, class _Tp> template <class _ForwardIterator, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) std::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category());
{
std::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -22,21 +22,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset. // fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
template <class _OutputIterator, class _Size, class _Tp> template <class _OutputIterator, class _Size, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
_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;
for (; __n > 0; ++__first, (void) --__n) return __first;
*__first = __value;
return __first;
} }
template <class _OutputIterator, class _Size, class _Tp> template <class _OutputIterator, class _Size, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
_OutputIterator fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) return std::__fill_n(__first, std::__convert_to_integral(__n), __value);
{
return std::__fill_n(__first, std::__convert_to_integral(__n), __value);
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -28,15 +28,14 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template < template < class _AlgPolicy,
class _AlgPolicy, class _Iter1,
class _Iter1, class _Sent1,
class _Sent1, class _Iter2,
class _Iter2, class _Sent2,
class _Sent2, class _Pred,
class _Pred, class _Proj1,
class _Proj1, class _Proj2>
class _Proj2>
_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __find_end_impl( _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __find_end_impl(
_Iter1 __first1, _Iter1 __first1,
_Sent1 __last1, _Sent1 __last1,
@ -49,7 +48,7 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1>
forward_iterator_tag) { forward_iterator_tag) {
// modeled after search algorithm // modeled after search algorithm
_Iter1 __match_first = _IterOps<_AlgPolicy>::next(__first1, __last1); // __last1 is the "default" answer _Iter1 __match_first = _IterOps<_AlgPolicy>::next(__first1, __last1); // __last1 is the "default" answer
_Iter1 __match_last = __match_first; _Iter1 __match_last = __match_first;
if (__first2 == __last2) if (__first2 == __last2)
return pair<_Iter1, _Iter1>(__match_last, __match_last); return pair<_Iter1, _Iter1>(__match_last, __match_last);
while (true) { while (true) {
@ -66,15 +65,14 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1>
while (true) { while (true) {
if (++__m2 == __last2) { // Pattern exhaused, record answer and search for another one if (++__m2 == __last2) { // Pattern exhaused, record answer and search for another one
__match_first = __first1; __match_first = __first1;
__match_last = ++__m1; __match_last = ++__m1;
++__first1; ++__first1;
break; break;
} }
if (++__m1 == __last1) // Source exhausted, return last answer if (++__m1 == __last1) // Source exhausted, return last answer
return pair<_Iter1, _Iter1>(__match_first, __match_last); return pair<_Iter1, _Iter1>(__match_first, __match_last);
// mismatch, restart with a new __first // mismatch, restart with a new __first
if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) {
{
++__first1; ++__first1;
break; break;
} // else there is a match, check next elements } // else there is a match, check next elements
@ -82,15 +80,14 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1>
} }
} }
template < template < class _IterOps,
class _IterOps, class _Pred,
class _Pred, class _Iter1,
class _Iter1, class _Sent1,
class _Sent1, class _Iter2,
class _Iter2, class _Sent2,
class _Sent2, class _Proj1,
class _Proj1, class _Proj2>
class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end( _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end(
_Iter1 __first1, _Iter1 __first1,
_Sent1 __sent1, _Sent1 __sent1,
@ -127,23 +124,21 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end(
return __last1; return __last1;
// 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))) if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) {
{
break; break;
} // else there is a match, check next elements } // else there is a match, check next elements
} }
} }
} }
template < template < class _AlgPolicy,
class _AlgPolicy, class _Pred,
class _Pred, class _Iter1,
class _Iter1, class _Sent1,
class _Sent1, class _Iter2,
class _Iter2, class _Sent2,
class _Sent2, class _Proj1,
class _Proj1, class _Proj2>
class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end( _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end(
_Iter1 __first1, _Iter1 __first1,
_Sent1 __sent1, _Sent1 __sent1,
@ -165,8 +160,8 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end(
if (__len1 < __len2) if (__len1 < __len2)
return __last1; return __last1;
const _Iter1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here const _Iter1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here
_Iter1 __l1 = __last1; _Iter1 __l1 = __last1;
_Iter2 __l2 = __last2; _Iter2 __l2 = __last2;
--__l2; --__l2;
while (true) { while (true) {
while (true) { while (true) {
@ -189,10 +184,12 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end(
} }
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_end_classic(
_ForwardIterator1 __find_end_classic(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator1 __first1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator1 __last1,
_BinaryPredicate& __pred) { _ForwardIterator2 __first2,
_ForwardIterator2 __last2,
_BinaryPredicate& __pred) {
auto __proj = __identity(); auto __proj = __identity();
return std::__find_end_impl<_ClassicAlgPolicy>( return std::__find_end_impl<_ClassicAlgPolicy>(
__first1, __first1,
@ -208,17 +205,18 @@ _ForwardIterator1 __find_end_classic(_ForwardIterator1 __first1, _ForwardIterato
} }
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_end(
_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator1 __first1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator1 __last1,
_BinaryPredicate __pred) { _ForwardIterator2 __first2,
_ForwardIterator2 __last2,
_BinaryPredicate __pred) {
return std::__find_end_classic(__first1, __last1, __first2, __last2, __pred); return std::__find_end_classic(__first1, __last1, __first2, __last2, __pred);
} }
template <class _ForwardIterator1, class _ForwardIterator2> template <class _ForwardIterator1, class _ForwardIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1
_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
_ForwardIterator2 __first2, _ForwardIterator2 __last2) {
return std::find_end(__first1, __last1, __first2, __last2, __equal_to()); return std::find_end(__first1, __last1, __first2, __last2, __equal_to());
} }

View File

@ -21,12 +21,12 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_first_of_ce(
_LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __first1,
_ForwardIterator1 __last1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _ForwardIterator2 __last2,
_BinaryPredicate&& __pred) { _BinaryPredicate&& __pred) {
for (; __first1 != __last1; ++__first1) for (; __first1 != __last1; ++__first1)
for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
if (__pred(*__first1, *__j)) if (__pred(*__first1, *__j))
@ -35,9 +35,12 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_first_of_ce(_ForwardItera
} }
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of(
find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator1 __first1,
_ForwardIterator2 __last2, _BinaryPredicate __pred) { _ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_ForwardIterator2 __last2,
_BinaryPredicate __pred) {
return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred); return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred);
} }

View File

@ -22,9 +22,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 17 #if _LIBCPP_STD_VER >= 17
template <class _InputIterator, class _Size, class _Function> template <class _InputIterator, class _Size, class _Function>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator for_each_n(_InputIterator __first, inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
_Size __orig_n, for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) {
_Function __f) {
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
_IntegralSize __n = __orig_n; _IntegralSize __n = __orig_n;
while (__n > 0) { while (__n > 0) {

View File

@ -18,12 +18,10 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator, class _Generator> template <class _ForwardIterator, class _Generator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) for (; __first != __last; ++__first)
{ *__first = __gen();
for (; __first != __last; ++__first)
*__first = __gen();
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -19,15 +19,13 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _OutputIterator, class _Size, class _Generator> template <class _OutputIterator, class _Size, class _Generator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
_OutputIterator generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) {
generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
{ _IntegralSize __n = __orig_n;
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; for (; __n > 0; ++__first, (void)--__n)
_IntegralSize __n = __orig_n; *__first = __gen();
for (; __n > 0; ++__first, (void) --__n) return __first;
*__first = __gen();
return __first;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -23,19 +23,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// Perform division by two quickly for positive integers (llvm.org/PR39129) // Perform division by two quickly for positive integers (llvm.org/PR39129)
template <typename _Integral, __enable_if_t<is_integral<_Integral>::value, int> = 0> template <typename _Integral, __enable_if_t<is_integral<_Integral>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Integral __half_positive(_Integral __value) {
_Integral return static_cast<_Integral>(static_cast<__make_unsigned_t<_Integral> >(__value) / 2);
__half_positive(_Integral __value)
{
return static_cast<_Integral>(static_cast<__make_unsigned_t<_Integral> >(__value) / 2);
} }
template <typename _Tp, __enable_if_t<!is_integral<_Tp>::value, int> = 0> template <typename _Tp, __enable_if_t<!is_integral<_Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp __half_positive(_Tp __value) {
_Tp return __value / 2;
__half_positive(_Tp __value)
{
return __value / 2;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -30,7 +30,7 @@ struct in_found_result {
template <class _InIter2> template <class _InIter2>
requires convertible_to<const _InIter1&, _InIter2> requires convertible_to<const _InIter1&, _InIter2>
_LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() const & { _LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() const& {
return {in, found}; return {in, found};
} }

View File

@ -30,7 +30,7 @@ struct in_fun_result {
template <class _InIter2, class _Func2> template <class _InIter2, class _Func2>
requires convertible_to<const _InIter1&, _InIter2> && convertible_to<const _Func1&, _Func2> requires convertible_to<const _InIter1&, _InIter2> && convertible_to<const _Func1&, _Func2>
_LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() const & { _LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() const& {
return {in, fun}; return {in, fun};
} }

View File

@ -31,18 +31,16 @@ struct in_in_out_result {
_LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out; _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out;
template <class _InIter3, class _InIter4, class _OutIter2> template <class _InIter3, class _InIter4, class _OutIter2>
requires convertible_to<const _InIter1&, _InIter3> requires convertible_to<const _InIter1&, _InIter3> && convertible_to<const _InIter2&, _InIter4> &&
&& convertible_to<const _InIter2&, _InIter4> && convertible_to<const _OutIter1&, _OutIter2> convertible_to<const _OutIter1&, _OutIter2>
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_HIDE_FROM_ABI constexpr operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() const& {
operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() const& {
return {in1, in2, out}; return {in1, in2, out};
} }
template <class _InIter3, class _InIter4, class _OutIter2> template <class _InIter3, class _InIter4, class _OutIter2>
requires convertible_to<_InIter1, _InIter3> requires convertible_to<_InIter1, _InIter3> && convertible_to<_InIter2, _InIter4> &&
&& convertible_to<_InIter2, _InIter4> && convertible_to<_OutIter1, _OutIter2> convertible_to<_OutIter1, _OutIter2>
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_HIDE_FROM_ABI constexpr operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() && {
operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() && {
return {std::move(in1), std::move(in2), std::move(out)}; return {std::move(in1), std::move(in2), std::move(out)};
} }
}; };

View File

@ -31,15 +31,13 @@ struct in_in_result {
template <class _InIter3, class _InIter4> template <class _InIter3, class _InIter4>
requires convertible_to<const _InIter1&, _InIter3> && convertible_to<const _InIter2&, _InIter4> requires convertible_to<const _InIter1&, _InIter3> && convertible_to<const _InIter2&, _InIter4>
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_HIDE_FROM_ABI constexpr operator in_in_result<_InIter3, _InIter4>() const& {
operator in_in_result<_InIter3, _InIter4>() const & {
return {in1, in2}; return {in1, in2};
} }
template <class _InIter3, class _InIter4> template <class _InIter3, class _InIter4>
requires convertible_to<_InIter1, _InIter3> && convertible_to<_InIter2, _InIter4> requires convertible_to<_InIter1, _InIter3> && convertible_to<_InIter2, _InIter4>
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_HIDE_FROM_ABI constexpr operator in_in_result<_InIter3, _InIter4>() && {
operator in_in_result<_InIter3, _InIter4>() && {
return {std::move(in1), std::move(in2)}; return {std::move(in1), std::move(in2)};
} }
}; };

View File

@ -30,18 +30,16 @@ struct in_out_out_result {
_LIBCPP_NO_UNIQUE_ADDRESS _OutIter2 out2; _LIBCPP_NO_UNIQUE_ADDRESS _OutIter2 out2;
template <class _InIter2, class _OutIter3, class _OutIter4> template <class _InIter2, class _OutIter3, class _OutIter4>
requires convertible_to<const _InIter1&, _InIter2> requires convertible_to<const _InIter1&, _InIter2> && convertible_to<const _OutIter1&, _OutIter3> &&
&& convertible_to<const _OutIter1&, _OutIter3> && convertible_to<const _OutIter2&, _OutIter4> convertible_to<const _OutIter2&, _OutIter4>
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_HIDE_FROM_ABI constexpr operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() const& {
operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() const& {
return {in, out1, out2}; return {in, out1, out2};
} }
template <class _InIter2, class _OutIter3, class _OutIter4> template <class _InIter2, class _OutIter3, class _OutIter4>
requires convertible_to<_InIter1, _InIter2> requires convertible_to<_InIter1, _InIter2> && convertible_to<_OutIter1, _OutIter3> &&
&& convertible_to<_OutIter1, _OutIter3> && convertible_to<_OutIter2, _OutIter4> convertible_to<_OutIter2, _OutIter4>
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_HIDE_FROM_ABI constexpr operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() && {
operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() && {
return {std::move(in), std::move(out1), std::move(out2)}; return {std::move(in), std::move(out1), std::move(out2)};
} }
}; };

View File

@ -27,22 +27,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges { namespace ranges {
template<class _InIter1, class _OutIter1> template <class _InIter1, class _OutIter1>
struct in_out_result { struct in_out_result {
_LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in; _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in;
_LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out; _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out;
template <class _InIter2, class _OutIter2> template <class _InIter2, class _OutIter2>
requires convertible_to<const _InIter1&, _InIter2> && convertible_to<const _OutIter1&, _OutIter2> requires convertible_to<const _InIter1&, _InIter2> && convertible_to<const _OutIter1&, _OutIter2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI constexpr operator in_out_result<_InIter2, _OutIter2>() const& {
constexpr operator in_out_result<_InIter2, _OutIter2>() const & {
return {in, out}; return {in, out};
} }
template <class _InIter2, class _OutIter2> template <class _InIter2, class _OutIter2>
requires convertible_to<_InIter1, _InIter2> && convertible_to<_OutIter1, _OutIter2> requires convertible_to<_InIter1, _InIter2> && convertible_to<_OutIter1, _OutIter2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI constexpr operator in_out_result<_InIter2, _OutIter2>() && {
constexpr operator in_out_result<_InIter2, _OutIter2>() && {
return {std::move(in), std::move(out)}; return {std::move(in), std::move(out)};
} }
}; };

View File

@ -25,12 +25,17 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Comp, class _Proj1, class _Proj2> template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Comp, class _Proj1, class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __includes(
__includes(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Iter1 __first1,
_Comp&& __comp, _Proj1&& __proj1, _Proj2&& __proj2) { _Sent1 __last1,
_Iter2 __first2,
_Sent2 __last2,
_Comp&& __comp,
_Proj1&& __proj1,
_Proj2&& __proj2) {
for (; __first2 != __last2; ++__first1) { for (; __first2 != __last2; ++__first1) {
if (__first1 == __last1 || std::__invoke( if (__first1 == __last1 ||
__comp, std::__invoke(__proj2, *__first2), std::__invoke(__proj1, *__first1))) std::__invoke(__comp, std::__invoke(__proj2, *__first2), std::__invoke(__proj1, *__first1)))
return false; return false;
if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
++__first2; ++__first2;
@ -39,14 +44,14 @@ __includes(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
} }
template <class _InputIterator1, class _InputIterator2, class _Compare> template <class _InputIterator1, class _InputIterator2, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool includes( _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
_InputIterator1 __first1, includes(_InputIterator1 __first1,
_InputIterator1 __last1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __first2,
_InputIterator2 __last2, _InputIterator2 __last2,
_Compare __comp) { _Compare __comp) {
static_assert(__is_callable<_Compare, decltype(*__first1), decltype(*__first2)>::value, static_assert(
"Comparator has to be callable"); __is_callable<_Compare, decltype(*__first1), decltype(*__first2)>::value, "Comparator has to be callable");
return std::__includes( return std::__includes(
std::move(__first1), std::move(__first1),

View File

@ -42,54 +42,57 @@ template <class _Predicate>
class __invert // invert the sense of a comparison class __invert // invert the sense of a comparison
{ {
private: private:
_Predicate __p_; _Predicate __p_;
public: public:
_LIBCPP_HIDE_FROM_ABI __invert() {} _LIBCPP_HIDE_FROM_ABI __invert() {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI explicit __invert(_Predicate __p) : __p_(__p) {}
explicit __invert(_Predicate __p) : __p_(__p) {}
template <class _T1> template <class _T1>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI bool operator()(const _T1& __x) {
bool operator()(const _T1& __x) {return !__p_(__x);} return !__p_(__x);
}
template <class _T1, class _T2> template <class _T1, class _T2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI bool operator()(const _T1& __x, const _T2& __y) {
bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);} return __p_(__y, __x);
}
}; };
template <class _AlgPolicy, class _Compare, class _InputIterator1, class _Sent1, template <class _AlgPolicy,
class _InputIterator2, class _Sent2, class _OutputIterator> class _Compare,
_LIBCPP_HIDE_FROM_ABI class _InputIterator1,
void __half_inplace_merge(_InputIterator1 __first1, _Sent1 __last1, class _Sent1,
_InputIterator2 __first2, _Sent2 __last2, class _InputIterator2,
_OutputIterator __result, _Compare&& __comp) class _Sent2,
{ class _OutputIterator>
for (; __first1 != __last1; ++__result) _LIBCPP_HIDE_FROM_ABI void __half_inplace_merge(
{ _InputIterator1 __first1,
if (__first2 == __last2) _Sent1 __last1,
{ _InputIterator2 __first2,
std::__move<_AlgPolicy>(__first1, __last1, __result); _Sent2 __last2,
return; _OutputIterator __result,
} _Compare&& __comp) {
for (; __first1 != __last1; ++__result) {
if (__comp(*__first2, *__first1)) if (__first2 == __last2) {
{ std::__move<_AlgPolicy>(__first1, __last1, __result);
*__result = _IterOps<_AlgPolicy>::__iter_move(__first2); return;
++__first2;
}
else
{
*__result = _IterOps<_AlgPolicy>::__iter_move(__first1);
++__first1;
}
} }
// __first2 through __last2 are already in the right spot.
if (__comp(*__first2, *__first1)) {
*__result = _IterOps<_AlgPolicy>::__iter_move(__first2);
++__first2;
} else {
*__result = _IterOps<_AlgPolicy>::__iter_move(__first1);
++__first1;
}
}
// __first2 through __last2 are already in the right spot.
} }
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator> template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI void __buffered_inplace_merge(
void __buffered_inplace_merge(
_BidirectionalIterator __first, _BidirectionalIterator __first,
_BidirectionalIterator __middle, _BidirectionalIterator __middle,
_BidirectionalIterator __last, _BidirectionalIterator __last,
@ -98,27 +101,25 @@ void __buffered_inplace_merge(
typename iterator_traits<_BidirectionalIterator>::difference_type __len2, typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
typename iterator_traits<_BidirectionalIterator>::value_type* __buff) { typename iterator_traits<_BidirectionalIterator>::value_type* __buff) {
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
__destruct_n __d(0); __destruct_n __d(0);
unique_ptr<value_type, __destruct_n&> __h2(__buff, __d); unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
if (__len1 <= __len2) if (__len1 <= __len2) {
{ value_type* __p = __buff;
value_type* __p = __buff; for (_BidirectionalIterator __i = __first; __i != __middle;
for (_BidirectionalIterator __i = __first; __i != __middle; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p) __d.template __incr<value_type>(), (void)++__i, (void)++__p)
::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i));
std::__half_inplace_merge<_AlgPolicy>(__buff, __p, __middle, __last, __first, __comp); std::__half_inplace_merge<_AlgPolicy>(__buff, __p, __middle, __last, __first, __comp);
} } else {
else value_type* __p = __buff;
{ for (_BidirectionalIterator __i = __middle; __i != __last;
value_type* __p = __buff; __d.template __incr<value_type>(), (void)++__i, (void)++__p)
for (_BidirectionalIterator __i = __middle; __i != __last; __d.template __incr<value_type>(), (void) ++__i, (void) ++__p) ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i));
::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); typedef __unconstrained_reverse_iterator<_BidirectionalIterator> _RBi;
typedef __unconstrained_reverse_iterator<_BidirectionalIterator> _RBi; typedef __unconstrained_reverse_iterator<value_type*> _Rv;
typedef __unconstrained_reverse_iterator<value_type*> _Rv; typedef __invert<_Compare> _Inverted;
typedef __invert<_Compare> _Inverted; std::__half_inplace_merge<_AlgPolicy>(
std::__half_inplace_merge<_AlgPolicy>(_Rv(__p), _Rv(__buff), _Rv(__p), _Rv(__buff), _RBi(__middle), _RBi(__first), _RBi(__last), _Inverted(__comp));
_RBi(__middle), _RBi(__first), }
_RBi(__last), _Inverted(__comp));
}
} }
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator> template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
@ -131,107 +132,92 @@ void __inplace_merge(
typename iterator_traits<_BidirectionalIterator>::difference_type __len2, typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
typename iterator_traits<_BidirectionalIterator>::value_type* __buff, typename iterator_traits<_BidirectionalIterator>::value_type* __buff,
ptrdiff_t __buff_size) { ptrdiff_t __buff_size) {
using _Ops = _IterOps<_AlgPolicy>; using _Ops = _IterOps<_AlgPolicy>;
typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
while (true) while (true) {
{ // if __middle == __last, we're done
// if __middle == __last, we're done if (__len2 == 0)
if (__len2 == 0) return;
return; if (__len1 <= __buff_size || __len2 <= __buff_size)
if (__len1 <= __buff_size || __len2 <= __buff_size) return std::__buffered_inplace_merge<_AlgPolicy>(__first, __middle, __last, __comp, __len1, __len2, __buff);
return std::__buffered_inplace_merge<_AlgPolicy> // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0
(__first, __middle, __last, __comp, __len1, __len2, __buff); for (; true; ++__first, (void)--__len1) {
// shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0 if (__len1 == 0)
for (; true; ++__first, (void) --__len1) return;
{ if (__comp(*__middle, *__first))
if (__len1 == 0) break;
return;
if (__comp(*__middle, *__first))
break;
}
// __first < __middle < __last
// *__first > *__middle
// partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that
// all elements in:
// [__first, __m1) <= [__middle, __m2)
// [__middle, __m2) < [__m1, __middle)
// [__m1, __middle) <= [__m2, __last)
// and __m1 or __m2 is in the middle of its range
_BidirectionalIterator __m1; // "median" of [__first, __middle)
_BidirectionalIterator __m2; // "median" of [__middle, __last)
difference_type __len11; // distance(__first, __m1)
difference_type __len21; // distance(__middle, __m2)
// binary search smaller range
if (__len1 < __len2)
{ // __len >= 1, __len2 >= 2
__len21 = __len2 / 2;
__m2 = __middle;
_Ops::advance(__m2, __len21);
__m1 = std::__upper_bound<_AlgPolicy>(__first, __middle, *__m2, __comp, std::__identity());
__len11 = _Ops::distance(__first, __m1);
}
else
{
if (__len1 == 1)
{ // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1
// It is known *__first > *__middle
_Ops::iter_swap(__first, __middle);
return;
}
// __len1 >= 2, __len2 >= 1
__len11 = __len1 / 2;
__m1 = __first;
_Ops::advance(__m1, __len11);
__m2 = std::lower_bound(__middle, __last, *__m1, __comp);
__len21 = _Ops::distance(__middle, __m2);
}
difference_type __len12 = __len1 - __len11; // distance(__m1, __middle)
difference_type __len22 = __len2 - __len21; // distance(__m2, __last)
// [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last)
// swap middle two partitions
__middle = std::__rotate<_AlgPolicy>(__m1, __middle, __m2).first;
// __len12 and __len21 now have swapped meanings
// merge smaller range with recursive call and larger with tail recursion elimination
if (__len11 + __len21 < __len12 + __len22)
{
std::__inplace_merge<_AlgPolicy>(
__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
__first = __middle;
__middle = __m2;
__len1 = __len12;
__len2 = __len22;
}
else
{
std::__inplace_merge<_AlgPolicy>(
__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
__last = __middle;
__middle = __m1;
__len1 = __len11;
__len2 = __len21;
}
} }
// __first < __middle < __last
// *__first > *__middle
// partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that
// all elements in:
// [__first, __m1) <= [__middle, __m2)
// [__middle, __m2) < [__m1, __middle)
// [__m1, __middle) <= [__m2, __last)
// and __m1 or __m2 is in the middle of its range
_BidirectionalIterator __m1; // "median" of [__first, __middle)
_BidirectionalIterator __m2; // "median" of [__middle, __last)
difference_type __len11; // distance(__first, __m1)
difference_type __len21; // distance(__middle, __m2)
// binary search smaller range
if (__len1 < __len2) { // __len >= 1, __len2 >= 2
__len21 = __len2 / 2;
__m2 = __middle;
_Ops::advance(__m2, __len21);
__m1 = std::__upper_bound<_AlgPolicy>(__first, __middle, *__m2, __comp, std::__identity());
__len11 = _Ops::distance(__first, __m1);
} else {
if (__len1 == 1) { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1
// It is known *__first > *__middle
_Ops::iter_swap(__first, __middle);
return;
}
// __len1 >= 2, __len2 >= 1
__len11 = __len1 / 2;
__m1 = __first;
_Ops::advance(__m1, __len11);
__m2 = std::lower_bound(__middle, __last, *__m1, __comp);
__len21 = _Ops::distance(__middle, __m2);
}
difference_type __len12 = __len1 - __len11; // distance(__m1, __middle)
difference_type __len22 = __len2 - __len21; // distance(__m2, __last)
// [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last)
// swap middle two partitions
__middle = std::__rotate<_AlgPolicy>(__m1, __middle, __m2).first;
// __len12 and __len21 now have swapped meanings
// merge smaller range with recursive call and larger with tail recursion elimination
if (__len11 + __len21 < __len12 + __len22) {
std::__inplace_merge<_AlgPolicy>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
__first = __middle;
__middle = __m2;
__len1 = __len12;
__len2 = __len22;
} else {
std::__inplace_merge<_AlgPolicy>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
__last = __middle;
__middle = __m1;
__len1 = __len11;
__len2 = __len21;
}
}
} }
template <class _AlgPolicy, class _BidirectionalIterator, class _Compare> template <class _AlgPolicy, class _BidirectionalIterator, class _Compare>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI void __inplace_merge(
void _BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare&& __comp) {
__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
_Compare&& __comp) typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
{ difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle);
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last);
typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; difference_type __buf_size = std::min(__len1, __len2);
difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); // TODO: Remove the use of std::get_temporary_buffer
difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); _LIBCPP_SUPPRESS_DEPRECATED_PUSH
difference_type __buf_size = std::min(__len1, __len2); pair<value_type*, ptrdiff_t> __buf = std::get_temporary_buffer<value_type>(__buf_size);
// TODO: Remove the use of std::get_temporary_buffer _LIBCPP_SUPPRESS_DEPRECATED_POP
_LIBCPP_SUPPRESS_DEPRECATED_PUSH unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first);
pair<value_type*, ptrdiff_t> __buf = std::get_temporary_buffer<value_type>(__buf_size); return std::__inplace_merge<_AlgPolicy>(
_LIBCPP_SUPPRESS_DEPRECATED_POP std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second);
unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first);
return std::__inplace_merge<_AlgPolicy>(
std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second);
} }
template <class _BidirectionalIterator, class _Compare> template <class _BidirectionalIterator, class _Compare>
@ -242,11 +228,9 @@ inline _LIBCPP_HIDE_FROM_ABI void inplace_merge(
} }
template <class _BidirectionalIterator> template <class _BidirectionalIterator>
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI void
void inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) {
inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less<>());
{
std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -22,21 +22,15 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _RandomAccessIterator, class _Compare> template <class _RandomAccessIterator, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
bool return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)) == __last;
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
{
return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)) == __last;
} }
template<class _RandomAccessIterator> template <class _RandomAccessIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
bool return std::is_heap(__first, __last, __less<>());
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
return std::is_heap(__first, __last, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -22,43 +22,39 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Compare, class _RandomAccessIterator> template <class _Compare, class _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) __is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) {
{ typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; difference_type __len = __last - __first;
difference_type __len = __last - __first; difference_type __p = 0;
difference_type __p = 0; difference_type __c = 1;
difference_type __c = 1; _RandomAccessIterator __pp = __first;
_RandomAccessIterator __pp = __first; while (__c < __len) {
while (__c < __len) _RandomAccessIterator __cp = __first + __c;
{ if (__comp(*__pp, *__cp))
_RandomAccessIterator __cp = __first + __c; return __cp;
if (__comp(*__pp, *__cp)) ++__c;
return __cp; ++__cp;
++__c; if (__c == __len)
++__cp; return __last;
if (__c == __len) if (__comp(*__pp, *__cp))
return __last; return __cp;
if (__comp(*__pp, *__cp)) ++__p;
return __cp; ++__pp;
++__p; __c = 2 * __p + 1;
++__pp; }
__c = 2 * __p + 1; return __last;
}
return __last;
} }
template <class _RandomAccessIterator, class _Compare> template <class _RandomAccessIterator, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
{ return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp));
return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp));
} }
template<class _RandomAccessIterator> template <class _RandomAccessIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) {
{ return std::__is_heap_until(__first, __last, __less<>());
return std::__is_heap_until(__first, __last, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -19,18 +19,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _Predicate> template <class _InputIterator, class _Predicate>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
{ for (; __first != __last; ++__first)
for (; __first != __last; ++__first) if (!__pred(*__first))
if (!__pred(*__first)) break;
break; if (__first == __last)
if ( __first == __last )
return true;
++__first;
for (; __first != __last; ++__first)
if (__pred(*__first))
return false;
return true; return true;
++__first;
for (; __first != __last; ++__first)
if (__pred(*__first))
return false;
return true;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -37,18 +37,24 @@ struct _ConstTimeDistance : false_type {};
#if _LIBCPP_STD_VER >= 20 #if _LIBCPP_STD_VER >= 20
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2> template <class _Iter1, class _Sent1, class _Iter2, class _Sent2>
struct _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2, __enable_if_t< struct _ConstTimeDistance<_Iter1,
sized_sentinel_for<_Sent1, _Iter1> && _Sent1,
sized_sentinel_for<_Sent2, _Iter2> _Iter2,
>> : true_type {}; _Sent2,
__enable_if_t< sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2> >>
: true_type {};
#else #else
template <class _Iter1, class _Iter2> template <class _Iter1, class _Iter2>
struct _ConstTimeDistance<_Iter1, _Iter1, _Iter2, _Iter2, __enable_if_t< struct _ConstTimeDistance<
is_same<typename iterator_traits<_Iter1>::iterator_category, random_access_iterator_tag>::value && _Iter1,
is_same<typename iterator_traits<_Iter2>::iterator_category, random_access_iterator_tag>::value _Iter1,
> > : true_type {}; _Iter2,
_Iter2,
__enable_if_t< is_same<typename iterator_traits<_Iter1>::iterator_category, random_access_iterator_tag>::value &&
is_same<typename iterator_traits<_Iter2>::iterator_category, random_access_iterator_tag>::value > >
: true_type {};
#endif // _LIBCPP_STD_VER >= 20 #endif // _LIBCPP_STD_VER >= 20
@ -56,11 +62,21 @@ struct _ConstTimeDistance<_Iter1, _Iter1, _Iter2, _Iter2, __enable_if_t<
// For each element in [f1, l1) see if there are the same number of equal elements in [f2, l2) // For each element in [f1, l1) see if there are the same number of equal elements in [f2, l2)
template <class _AlgPolicy, template <class _AlgPolicy,
class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Iter1,
class _Proj1, class _Proj2, class _Pred> class _Sent1,
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool class _Iter2,
__is_permutation_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, class _Sent2,
_Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) { class _Proj1,
class _Proj2,
class _Pred>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation_impl(
_Iter1 __first1,
_Sent1 __last1,
_Iter2 __first2,
_Sent2 __last2,
_Pred&& __pred,
_Proj1&& __proj1,
_Proj2&& __proj2) {
using _D1 = __iter_diff_t<_Iter1>; using _D1 = __iter_diff_t<_Iter1>;
for (auto __i = __first1; __i != __last1; ++__i) { for (auto __i = __first1; __i != __last1; ++__i) {
@ -97,9 +113,8 @@ __is_permutation_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 _
// 2+1 iterators, predicate. Not used by range algorithms. // 2+1 iterators, predicate. Not used by range algorithms.
template <class _AlgPolicy, class _ForwardIterator1, class _Sentinel1, class _ForwardIterator2, class _BinaryPredicate> template <class _AlgPolicy, class _ForwardIterator1, class _Sentinel1, class _ForwardIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation(
__is_permutation(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _BinaryPredicate&& __pred) {
_BinaryPredicate&& __pred) {
// Shorten sequences as much as possible by lopping of any equal prefix. // Shorten sequences as much as possible by lopping of any equal prefix.
for (; __first1 != __last1; ++__first1, (void)++__first2) { for (; __first1 != __last1; ++__first1, (void)++__first2) {
if (!__pred(*__first1, *__first2)) if (!__pred(*__first1, *__first2))
@ -111,24 +126,39 @@ __is_permutation(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterato
// __first1 != __last1 && *__first1 != *__first2 // __first1 != __last1 && *__first1 != *__first2
using _D1 = __iter_diff_t<_ForwardIterator1>; using _D1 = __iter_diff_t<_ForwardIterator1>;
_D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1);
if (__l1 == _D1(1)) if (__l1 == _D1(1))
return false; return false;
auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __l1); auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __l1);
return std::__is_permutation_impl<_AlgPolicy>( return std::__is_permutation_impl<_AlgPolicy>(
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::move(__first1),
__pred, __identity(), __identity()); std::move(__last1),
std::move(__first2),
std::move(__last2),
__pred,
__identity(),
__identity());
} }
// 2+2 iterators, predicate, non-constant time `distance`. // 2+2 iterators, predicate, non-constant time `distance`.
template <class _AlgPolicy, template <class _AlgPolicy,
class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Iter1,
class _Proj1, class _Proj2, class _Pred> class _Sent1,
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool class _Iter2,
__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, class _Sent2,
_Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2, class _Proj1,
/*_ConstTimeDistance=*/false_type) { class _Proj2,
class _Pred>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation(
_Iter1 __first1,
_Sent1 __last1,
_Iter2 __first2,
_Sent2 __last2,
_Pred&& __pred,
_Proj1&& __proj1,
_Proj2&& __proj2,
/*_ConstTimeDistance=*/false_type) {
// Shorten sequences as much as possible by lopping of any equal prefix. // Shorten sequences as much as possible by lopping of any equal prefix.
while (__first1 != __last1 && __first2 != __last2) { while (__first1 != __last1 && __first2 != __last2) {
if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
@ -143,44 +173,73 @@ __is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last
return false; return false;
using _D1 = __iter_diff_t<_Iter1>; using _D1 = __iter_diff_t<_Iter1>;
_D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1);
using _D2 = __iter_diff_t<_Iter2>; using _D2 = __iter_diff_t<_Iter2>;
_D2 __l2 = _IterOps<_AlgPolicy>::distance(__first2, __last2); _D2 __l2 = _IterOps<_AlgPolicy>::distance(__first2, __last2);
if (__l1 != __l2) if (__l1 != __l2)
return false; return false;
return std::__is_permutation_impl<_AlgPolicy>( return std::__is_permutation_impl<_AlgPolicy>(
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);
__pred, __proj1, __proj2);
} }
// 2+2 iterators, predicate, specialization for constant-time `distance` call. // 2+2 iterators, predicate, specialization for constant-time `distance` call.
template <class _AlgPolicy, template <class _AlgPolicy,
class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Iter1,
class _Proj1, class _Proj2, class _Pred> class _Sent1,
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool class _Iter2,
__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, class _Sent2,
_Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2, class _Proj1,
/*_ConstTimeDistance=*/true_type) { class _Proj2,
class _Pred>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation(
_Iter1 __first1,
_Sent1 __last1,
_Iter2 __first2,
_Sent2 __last2,
_Pred&& __pred,
_Proj1&& __proj1,
_Proj2&& __proj2,
/*_ConstTimeDistance=*/true_type) {
if (std::distance(__first1, __last1) != std::distance(__first2, __last2)) if (std::distance(__first1, __last1) != std::distance(__first2, __last2))
return false; return false;
return std::__is_permutation<_AlgPolicy>( return std::__is_permutation<_AlgPolicy>(
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::move(__first1),
__pred, __proj1, __proj2, std::move(__last1),
std::move(__first2),
std::move(__last2),
__pred,
__proj1,
__proj2,
/*_ConstTimeDistance=*/false_type()); /*_ConstTimeDistance=*/false_type());
} }
// 2+2 iterators, predicate // 2+2 iterators, predicate
template <class _AlgPolicy, template <class _AlgPolicy,
class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Iter1,
class _Proj1, class _Proj2, class _Pred> class _Sent1,
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool class _Iter2,
__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, class _Sent2,
_Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) { class _Proj1,
class _Proj2,
class _Pred>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation(
_Iter1 __first1,
_Sent1 __last1,
_Iter2 __first2,
_Sent2 __last2,
_Pred&& __pred,
_Proj1&& __proj1,
_Proj2&& __proj2) {
return std::__is_permutation<_AlgPolicy>( return std::__is_permutation<_AlgPolicy>(
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::move(__first1),
__pred, __proj1, __proj2, std::move(__last1),
std::move(__first2),
std::move(__last2),
__pred,
__proj1,
__proj2,
_ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2>()); _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2>());
} }
@ -188,14 +247,12 @@ __is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last
// 2+1 iterators, predicate // 2+1 iterators, predicate
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __pred) {
_BinaryPredicate __pred) {
static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value,
"The predicate has to be callable"); "The predicate has to be callable");
return std::__is_permutation<_ClassicAlgPolicy>( return std::__is_permutation<_ClassicAlgPolicy>(std::move(__first1), std::move(__last1), std::move(__first2), __pred);
std::move(__first1), std::move(__last1), std::move(__first2), __pred);
} }
// 2+1 iterators // 2+1 iterators
@ -223,15 +280,23 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
// 2+2 iterators, predicate // 2+2 iterators, predicate
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator1 __first1,
_ForwardIterator2 __last2, _BinaryPredicate __pred) { _ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_ForwardIterator2 __last2,
_BinaryPredicate __pred) {
static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value,
"The predicate has to be callable"); "The predicate has to be callable");
return std::__is_permutation<_ClassicAlgPolicy>( return std::__is_permutation<_ClassicAlgPolicy>(
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::move(__first1),
__pred, __identity(), __identity()); std::move(__last1),
std::move(__first2),
std::move(__last2),
__pred,
__identity(),
__identity());
} }
#endif // _LIBCPP_STD_VER >= 14 #endif // _LIBCPP_STD_VER >= 14

View File

@ -22,21 +22,15 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator, class _Compare> template <class _ForwardIterator, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
bool return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp) == __last;
is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{
return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp) == __last;
} }
template<class _ForwardIterator> template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 is_sorted(_ForwardIterator __first, _ForwardIterator __last) {
bool return std::is_sorted(__first, __last, __less<>());
is_sorted(_ForwardIterator __first, _ForwardIterator __last)
{
return std::is_sorted(__first, __last, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -22,33 +22,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Compare, class _ForwardIterator> template <class _Compare, class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) __is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
{ if (__first != __last) {
if (__first != __last) _ForwardIterator __i = __first;
{ while (++__i != __last) {
_ForwardIterator __i = __first; if (__comp(*__i, *__first))
while (++__i != __last) return __i;
{ __first = __i;
if (__comp(*__i, *__first))
return __i;
__first = __i;
}
} }
return __last; }
return __last;
} }
template <class _ForwardIterator, class _Compare> template <class _ForwardIterator, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
{ return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp);
return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp);
} }
template<class _ForwardIterator> template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) {
{ return std::is_sorted_until(__first, __last, __less<>());
return std::is_sorted_until(__first, __last, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -20,8 +20,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator1, class _ForwardIterator2> template <class _ForwardIterator1, class _ForwardIterator2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void iter_swap(_ForwardIterator1 __a, inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b)
_ForwardIterator2 __b)
// _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b))) // _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b)))
_NOEXCEPT_(_NOEXCEPT_(swap(*std::declval<_ForwardIterator1>(), *std::declval<_ForwardIterator2>()))) { _NOEXCEPT_(_NOEXCEPT_(swap(*std::declval<_ForwardIterator1>(), *std::declval<_ForwardIterator2>()))) {
swap(*__a, *__b); swap(*__a, *__b);

View File

@ -38,14 +38,14 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy> struct _IterOps; template <class _AlgPolicy>
struct _IterOps;
#if _LIBCPP_STD_VER >= 20 #if _LIBCPP_STD_VER >= 20
struct _RangeAlgPolicy {}; struct _RangeAlgPolicy {};
template <> template <>
struct _IterOps<_RangeAlgPolicy> { struct _IterOps<_RangeAlgPolicy> {
template <class _Iter> template <class _Iter>
using __value_type = iter_value_t<_Iter>; using __value_type = iter_value_t<_Iter>;
@ -55,12 +55,12 @@ struct _IterOps<_RangeAlgPolicy> {
template <class _Iter> template <class _Iter>
using __difference_type = iter_difference_t<_Iter>; using __difference_type = iter_difference_t<_Iter>;
static constexpr auto advance = ranges::advance; static constexpr auto advance = ranges::advance;
static constexpr auto distance = ranges::distance; static constexpr auto distance = ranges::distance;
static constexpr auto __iter_move = ranges::iter_move; static constexpr auto __iter_move = ranges::iter_move;
static constexpr auto iter_swap = ranges::iter_swap; static constexpr auto iter_swap = ranges::iter_swap;
static constexpr auto next = ranges::next; static constexpr auto next = ranges::next;
static constexpr auto prev = ranges::prev; static constexpr auto prev = ranges::prev;
static constexpr auto __advance_to = ranges::advance; static constexpr auto __advance_to = ranges::advance;
}; };
@ -70,7 +70,6 @@ struct _ClassicAlgPolicy {};
template <> template <>
struct _IterOps<_ClassicAlgPolicy> { struct _IterOps<_ClassicAlgPolicy> {
template <class _Iter> template <class _Iter>
using __value_type = typename iterator_traits<_Iter>::value_type; using __value_type = typename iterator_traits<_Iter>::value_type;
@ -82,15 +81,14 @@ struct _IterOps<_ClassicAlgPolicy> {
// advance // advance
template <class _Iter, class _Distance> template <class _Iter, class _Distance>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static void advance(_Iter& __iter, _Distance __count) {
static void advance(_Iter& __iter, _Distance __count) {
std::advance(__iter, __count); std::advance(__iter, __count);
} }
// distance // distance
template <class _Iter> template <class _Iter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static typename iterator_traits<_Iter>::difference_type
static typename iterator_traits<_Iter>::difference_type distance(_Iter __first, _Iter __last) { distance(_Iter __first, _Iter __last) {
return std::distance(__first, __last); return std::distance(__first, __last);
} }
@ -101,9 +99,9 @@ struct _IterOps<_ClassicAlgPolicy> {
using __move_t = decltype(std::move(*std::declval<_Iter&>())); using __move_t = decltype(std::move(*std::declval<_Iter&>()));
template <class _Iter> template <class _Iter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static void __validate_iter_reference() {
static void __validate_iter_reference() { static_assert(
static_assert(is_same<__deref_t<_Iter>, typename iterator_traits<__remove_cvref_t<_Iter> >::reference>::value, is_same<__deref_t<_Iter>, typename iterator_traits<__remove_cvref_t<_Iter> >::reference>::value,
"It looks like your iterator's `iterator_traits<It>::reference` does not match the return type of " "It looks like your iterator's `iterator_traits<It>::reference` does not match the return type of "
"dereferencing the iterator, i.e., calling `*it`. This is undefined behavior according to [input.iterators] " "dereferencing the iterator, i.e., calling `*it`. This is undefined behavior according to [input.iterators] "
"and can lead to dangling reference issues at runtime, so we are flagging this."); "and can lead to dangling reference issues at runtime, so we are flagging this.");
@ -112,10 +110,10 @@ struct _IterOps<_ClassicAlgPolicy> {
// iter_move // iter_move
template <class _Iter, __enable_if_t<is_reference<__deref_t<_Iter> >::value, int> = 0> template <class _Iter, __enable_if_t<is_reference<__deref_t<_Iter> >::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static
// If the result of dereferencing `_Iter` is a reference type, deduce the result of calling `std::move` on it. Note // If the result of dereferencing `_Iter` is a reference type, deduce the result of calling `std::move` on it.
// that the C++03 mode doesn't support `decltype(auto)` as the return type. // Note that the C++03 mode doesn't support `decltype(auto)` as the return type.
__move_t<_Iter> __move_t<_Iter>
__iter_move(_Iter&& __i) { __iter_move(_Iter&& __i) {
__validate_iter_reference<_Iter>(); __validate_iter_reference<_Iter>();
return std::move(*std::forward<_Iter>(__i)); return std::move(*std::forward<_Iter>(__i));
@ -123,11 +121,11 @@ struct _IterOps<_ClassicAlgPolicy> {
template <class _Iter, __enable_if_t<!is_reference<__deref_t<_Iter> >::value, int> = 0> template <class _Iter, __enable_if_t<!is_reference<__deref_t<_Iter> >::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static
// If the result of dereferencing `_Iter` is a value type, deduce the return value of this function to also be a // If the result of dereferencing `_Iter` is a value type, deduce the return value of this function to also be a
// value -- otherwise, after `operator*` returns a temporary, this function would return a dangling reference to that // value -- otherwise, after `operator*` returns a temporary, this function would return a dangling reference to
// temporary. Note that the C++03 mode doesn't support `auto` as the return type. // that temporary. Note that the C++03 mode doesn't support `auto` as the return type.
__deref_t<_Iter> __deref_t<_Iter>
__iter_move(_Iter&& __i) { __iter_move(_Iter&& __i) {
__validate_iter_reference<_Iter>(); __validate_iter_reference<_Iter>();
return *std::forward<_Iter>(__i); return *std::forward<_Iter>(__i);
@ -135,36 +133,31 @@ struct _IterOps<_ClassicAlgPolicy> {
// iter_swap // iter_swap
template <class _Iter1, class _Iter2> template <class _Iter1, class _Iter2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static void iter_swap(_Iter1&& __a, _Iter2&& __b) {
static void iter_swap(_Iter1&& __a, _Iter2&& __b) {
std::iter_swap(std::forward<_Iter1>(__a), std::forward<_Iter2>(__b)); std::iter_swap(std::forward<_Iter1>(__a), std::forward<_Iter2>(__b));
} }
// next // next
template <class _Iterator> template <class _Iterator>
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iterator next(_Iterator, _Iterator __last) {
_Iterator next(_Iterator, _Iterator __last) {
return __last; return __last;
} }
template <class _Iter> template <class _Iter>
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 __remove_cvref_t<_Iter>
__remove_cvref_t<_Iter> next(_Iter&& __it, next(_Iter&& __it, typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) {
typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) {
return std::next(std::forward<_Iter>(__it), __n); return std::next(std::forward<_Iter>(__it), __n);
} }
// prev // prev
template <class _Iter> template <class _Iter>
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 __remove_cvref_t<_Iter>
__remove_cvref_t<_Iter> prev(_Iter&& __iter, prev(_Iter&& __iter, typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) {
typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) {
return std::prev(std::forward<_Iter>(__iter), __n); return std::prev(std::forward<_Iter>(__iter), __n);
} }
template <class _Iter> template <class _Iter>
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 void __advance_to(_Iter& __first, _Iter __last) {
void __advance_to(_Iter& __first, _Iter __last) {
__first = __last; __first = __last;
} }
}; };

View File

@ -21,38 +21,35 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Compare, class _InputIterator1, class _InputIterator2> template <class _Compare, class _InputIterator1, class _InputIterator2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __lexicographical_compare(
__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator1 __first1,
_InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) _InputIterator1 __last1,
{ _InputIterator2 __first2,
for (; __first2 != __last2; ++__first1, (void) ++__first2) _InputIterator2 __last2,
{ _Compare __comp) {
if (__first1 == __last1 || __comp(*__first1, *__first2)) for (; __first2 != __last2; ++__first1, (void)++__first2) {
return true; if (__first1 == __last1 || __comp(*__first1, *__first2))
if (__comp(*__first2, *__first1)) return true;
return false; if (__comp(*__first2, *__first1))
} return false;
return false; }
return false;
} }
template <class _InputIterator1, class _InputIterator2, class _Compare> template <class _InputIterator1, class _InputIterator2, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare(
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator1 __first1,
bool _InputIterator1 __last1,
lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
_InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) _InputIterator2 __last2,
{ _Compare __comp) {
return std::__lexicographical_compare<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __comp); return std::__lexicographical_compare<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __comp);
} }
template <class _InputIterator1, class _InputIterator2> template <class _InputIterator1, class _InputIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare(
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
bool return std::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>());
lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2)
{
return std::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -28,8 +28,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, 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_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter
_Iter __lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) { __lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
auto __len = _IterOps<_AlgPolicy>::distance(__first, __last); auto __len = _IterOps<_AlgPolicy>::distance(__first, __last);
while (__len != 0) { while (__len != 0) {
@ -47,17 +47,16 @@ _Iter __lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp& __
} }
template <class _ForwardIterator, class _Tp, class _Compare> template <class _ForwardIterator, class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) {
static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable");
"The comparator has to be callable");
auto __proj = std::__identity(); auto __proj = std::__identity();
return std::__lower_bound<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj); return std::__lower_bound<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj);
} }
template <class _ForwardIterator, class _Tp> template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
return std::lower_bound(__first, __last, __value, __less<>()); return std::lower_bound(__first, __last, __value, __less<>());
} }

View File

@ -27,29 +27,29 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) {
__comp_ref_type<_Compare> __comp_ref = __comp; __comp_ref_type<_Compare> __comp_ref = __comp;
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
difference_type __n = __last - __first; difference_type __n = __last - __first;
if (__n > 1) { if (__n > 1) {
// start from the first parent, there is no need to consider children // start from the first parent, there is no need to consider children
for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) { for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) {
std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start); std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start);
} }
} }
} }
template <class _RandomAccessIterator, class _Compare> template <class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
std::__make_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); std::__make_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp);
} }
template <class _RandomAccessIterator> template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::make_heap(std::move(__first), std::move(__last), __less<>()); std::make_heap(std::move(__first), std::move(__last), __less<>());
} }

View File

@ -36,44 +36,38 @@ struct _ProjectedPred {
: __pred(__pred_arg), __proj(__proj_arg) {} : __pred(__pred_arg), __proj(__proj_arg) {}
template <class _Tp> template <class _Tp>
typename __invoke_of<_Pred&, typename __invoke_of<_Pred&, decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>())) >::
decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>())) type _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI
>::type operator()(_Tp&& __v) const {
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_Tp&& __v) const {
return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v))); return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v)));
} }
template <class _T1, class _T2> template <class _T1, class _T2>
typename __invoke_of<_Pred&, typename __invoke_of<_Pred&,
decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())), decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())),
decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>())) decltype(std::__invoke(std::declval<_Proj&>(),
>::type std::declval<_T2>())) >::type _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_T1&& __lhs, _T2&& __rhs) const { operator()(_T1&& __lhs, _T2&& __rhs) const {
return std::__invoke(__pred, return std::__invoke(
std::__invoke(__proj, std::forward<_T1>(__lhs)), __pred, std::__invoke(__proj, std::forward<_T1>(__lhs)), std::__invoke(__proj, std::forward<_T2>(__rhs)));
std::__invoke(__proj, std::forward<_T2>(__rhs)));
} }
}; };
template <class _Pred, template <
class _Proj, class _Pred,
__enable_if_t<!(!is_member_pointer<__decay_t<_Pred> >::value && class _Proj,
__is_identity<__decay_t<_Proj> >::value), __enable_if_t<!(!is_member_pointer<__decay_t<_Pred> >::value && __is_identity<__decay_t<_Proj> >::value), int> = 0>
int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj> __make_projected(_Pred& __pred, _Proj& __proj) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj>
__make_projected(_Pred& __pred, _Proj& __proj) {
return _ProjectedPred<_Pred, _Proj>(__pred, __proj); return _ProjectedPred<_Pred, _Proj>(__pred, __proj);
} }
// Avoid creating the functor and just use the pristine comparator -- for certain algorithms, this would enable // Avoid creating the functor and just use the pristine comparator -- for certain algorithms, this would enable
// optimizations that rely on the type of the comparator. Additionally, this results in less layers of indirection in // optimizations that rely on the type of the comparator. Additionally, this results in less layers of indirection in
// the call stack when the comparator is invoked, even in an unoptimized build. // the call stack when the comparator is invoked, even in an unoptimized build.
template <class _Pred, template <
class _Proj, class _Pred,
__enable_if_t<!is_member_pointer<__decay_t<_Pred> >::value && class _Proj,
__is_identity<__decay_t<_Proj> >::value, __enable_if_t<!is_member_pointer<__decay_t<_Pred> >::value && __is_identity<__decay_t<_Proj> >::value, int> = 0>
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Pred& __make_projected(_Pred& __pred, _Proj&) { _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Pred& __make_projected(_Pred& __pred, _Proj&) {
return __pred; return __pred;
} }
@ -87,8 +81,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges { namespace ranges {
template <class _Comp, class _Proj1, class _Proj2> template <class _Comp, class _Proj1, class _Proj2>
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
if constexpr (__is_identity<decay_t<_Proj1>>::value && __is_identity<decay_t<_Proj2>>::value && if constexpr (__is_identity<decay_t<_Proj1>>::value && __is_identity<decay_t<_Proj2>>::value &&
!is_member_pointer_v<decay_t<_Comp>>) { !is_member_pointer_v<decay_t<_Comp>>) {
// Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable // Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable
@ -98,8 +91,8 @@ decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __p
} else { } else {
return [&](auto&& __lhs, auto&& __rhs) -> bool { return [&](auto&& __lhs, auto&& __rhs) -> bool {
return std::invoke(__comp, return std::invoke(__comp,
std::invoke(__proj1, std::forward<decltype(__lhs)>(__lhs)), std::invoke(__proj1, std::forward<decltype(__lhs)>(__lhs)),
std::invoke(__proj2, std::forward<decltype(__rhs)>(__rhs))); std::invoke(__proj2, std::forward<decltype(__rhs)>(__rhs)));
}; };
} }
} }

View File

@ -25,41 +25,28 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp, class _Compare> template <class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) {
const _Tp& return __comp(__a, __b) ? __b : __a;
max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
{
return __comp(__a, __b) ? __b : __a;
} }
template <class _Tp> template <class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) {
const _Tp& return std::max(__a, __b, __less<>());
max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
{
return std::max(__a, __b, __less<>());
} }
#ifndef _LIBCPP_CXX03_LANG #ifndef _LIBCPP_CXX03_LANG
template<class _Tp, class _Compare> template <class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 max(initializer_list<_Tp> __t, _Compare __comp) {
_Tp return *std::__max_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp);
max(initializer_list<_Tp> __t, _Compare __comp)
{
return *std::__max_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp);
} }
template<class _Tp> template <class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp max(initializer_list<_Tp> __t) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 return *std::max_element(__t.begin(), __t.end(), __less<>());
_Tp
max(initializer_list<_Tp> __t)
{
return *std::max_element(__t.begin(), __t.end(), __less<>());
} }
#endif // _LIBCPP_CXX03_LANG #endif // _LIBCPP_CXX03_LANG

View File

@ -22,33 +22,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Compare, class _ForwardIterator> template <class _Compare, class _ForwardIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) __max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
{ static_assert(
static_assert(__has_forward_iterator_category<_ForwardIterator>::value, __has_forward_iterator_category<_ForwardIterator>::value, "std::max_element requires a ForwardIterator");
"std::max_element requires a ForwardIterator"); if (__first != __last) {
if (__first != __last) _ForwardIterator __i = __first;
{ while (++__i != __last)
_ForwardIterator __i = __first; if (__comp(*__first, *__i))
while (++__i != __last) __first = __i;
if (__comp(*__first, *__i)) }
__first = __i; return __first;
}
return __first;
} }
template <class _ForwardIterator, class _Compare> template <class _ForwardIterator, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
{ return std::__max_element<__comp_ref_type<_Compare> >(__first, __last, __comp);
return std::__max_element<__comp_ref_type<_Compare> >(__first, __last, __comp);
} }
template <class _ForwardIterator> template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
max_element(_ForwardIterator __first, _ForwardIterator __last) max_element(_ForwardIterator __first, _ForwardIterator __last) {
{ return std::max_element(__first, __last, __less<>());
return std::max_element(__first, __last, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -22,45 +22,46 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator __merge(
_OutputIterator _InputIterator1 __first1,
__merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) _InputIterator2 __first2,
{ _InputIterator2 __last2,
for (; __first1 != __last1; ++__result) _OutputIterator __result,
{ _Compare __comp) {
if (__first2 == __last2) for (; __first1 != __last1; ++__result) {
return std::copy(__first1, __last1, __result); if (__first2 == __last2)
if (__comp(*__first2, *__first1)) return std::copy(__first1, __last1, __result);
{ if (__comp(*__first2, *__first1)) {
*__result = *__first2; *__result = *__first2;
++__first2; ++__first2;
} } else {
else *__result = *__first1;
{ ++__first1;
*__result = *__first1;
++__first1;
}
} }
return std::copy(__first2, __last2, __result); }
return std::copy(__first2, __last2, __result);
} }
template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
_OutputIterator merge(_InputIterator1 __first1,
merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) _InputIterator2 __first2,
{ _InputIterator2 __last2,
return std::__merge<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __result, __comp); _OutputIterator __result,
_Compare __comp) {
return std::__merge<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __result, __comp);
} }
template <class _InputIterator1, class _InputIterator2, class _OutputIterator> template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
_OutputIterator merge(_InputIterator1 __first1,
merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) _InputIterator2 __first2,
{ _InputIterator2 __last2,
return std::merge(__first1, __last1, __first2, __last2, __result, __less<>()); _OutputIterator __result) {
return std::merge(__first1, __last1, __first2, __last2, __result, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -25,41 +25,28 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp, class _Compare> template <class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) {
const _Tp& return __comp(__b, __a) ? __b : __a;
min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
{
return __comp(__b, __a) ? __b : __a;
} }
template <class _Tp> template <class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) {
const _Tp& return std::min(__a, __b, __less<>());
min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
{
return std::min(__a, __b, __less<>());
} }
#ifndef _LIBCPP_CXX03_LANG #ifndef _LIBCPP_CXX03_LANG
template<class _Tp, class _Compare> template <class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 min(initializer_list<_Tp> __t, _Compare __comp) {
_Tp return *std::__min_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp);
min(initializer_list<_Tp> __t, _Compare __comp)
{
return *std::__min_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp);
} }
template<class _Tp> template <class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp min(initializer_list<_Tp> __t) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 return *std::min_element(__t.begin(), __t.end(), __less<>());
_Tp
min(initializer_list<_Tp> __t)
{
return *std::min_element(__t.begin(), __t.end(), __less<>());
} }
#endif // _LIBCPP_CXX03_LANG #endif // _LIBCPP_CXX03_LANG

View File

@ -28,8 +28,8 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Comp, class _Iter, class _Sent, class _Proj> template <class _Comp, class _Iter, class _Sent, class _Proj>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
_Iter __min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) { __min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) {
if (__first == __last) if (__first == __last)
return __first; return __first;
@ -42,29 +42,26 @@ _Iter __min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) {
} }
template <class _Comp, class _Iter, class _Sent> template <class _Comp, class _Iter, class _Sent>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter __min_element(_Iter __first, _Sent __last, _Comp __comp) {
_Iter __min_element(_Iter __first, _Sent __last, _Comp __comp) {
auto __proj = __identity(); auto __proj = __identity();
return std::__min_element<_Comp>(std::move(__first), std::move(__last), __comp, __proj); return std::__min_element<_Comp>(std::move(__first), std::move(__last), __comp, __proj);
} }
template <class _ForwardIterator, class _Compare> template <class _ForwardIterator, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
{ static_assert(
static_assert(__has_forward_iterator_category<_ForwardIterator>::value, __has_forward_iterator_category<_ForwardIterator>::value, "std::min_element requires a ForwardIterator");
"std::min_element requires a ForwardIterator"); static_assert(
static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, __is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, "The comparator has to be callable");
"The comparator has to be callable");
return std::__min_element<__comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp); return std::__min_element<__comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp);
} }
template <class _ForwardIterator> template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
min_element(_ForwardIterator __first, _ForwardIterator __last) min_element(_ForwardIterator __first, _ForwardIterator __last) {
{ return std::min_element(__first, __last, __less<>());
return std::min_element(__first, __last, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -34,7 +34,7 @@ struct min_max_result {
template <class _T2> template <class _T2>
requires convertible_to<const _T1&, _T2> requires convertible_to<const _T1&, _T2>
_LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() const & { _LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() const& {
return {min, max}; return {min, max};
} }

View File

@ -23,43 +23,33 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template<class _Tp, class _Compare> template <class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<const _Tp&, const _Tp&>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) {
pair<const _Tp&, const _Tp&> return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) : pair<const _Tp&, const _Tp&>(__a, __b);
minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
{
return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) :
pair<const _Tp&, const _Tp&>(__a, __b);
} }
template<class _Tp> template <class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<const _Tp&, const _Tp&>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) {
pair<const _Tp&, const _Tp&> return std::minmax(__a, __b, __less<>());
minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
{
return std::minmax(__a, __b, __less<>());
} }
#ifndef _LIBCPP_CXX03_LANG #ifndef _LIBCPP_CXX03_LANG
template<class _Tp, class _Compare> template <class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp>
pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t, _Compare __comp) { minmax(initializer_list<_Tp> __t, _Compare __comp) {
static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable"); static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable");
__identity __proj; __identity __proj;
auto __ret = std::__minmax_element_impl(__t.begin(), __t.end(), __comp, __proj); auto __ret = std::__minmax_element_impl(__t.begin(), __t.end(), __comp, __proj);
return pair<_Tp, _Tp>(*__ret.first, *__ret.second); return pair<_Tp, _Tp>(*__ret.first, *__ret.second);
} }
template<class _Tp> template <class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 minmax(initializer_list<_Tp> __t) {
pair<_Tp, _Tp> return std::minmax(__t, __less<>());
minmax(initializer_list<_Tp> __t)
{
return std::minmax(__t, __less<>());
} }
#endif // _LIBCPP_CXX03_LANG #endif // _LIBCPP_CXX03_LANG

View File

@ -29,19 +29,18 @@ class _MinmaxElementLessFunc {
_Proj& __proj_; _Proj& __proj_;
public: public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _MinmaxElementLessFunc(_Comp& __comp, _Proj& __proj)
_MinmaxElementLessFunc(_Comp& __comp, _Proj& __proj) : __comp_(__comp), __proj_(__proj) {} : __comp_(__comp), __proj_(__proj) {}
template <class _Iter> template <class _Iter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(_Iter& __it1, _Iter& __it2) {
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));
} }
}; };
template <class _Iter, class _Sent, class _Proj, class _Comp> template <class _Iter, class _Sent, class _Proj, class _Comp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter>
pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
auto __less = _MinmaxElementLessFunc<_Comp, _Proj>(__comp, __proj); auto __less = _MinmaxElementLessFunc<_Comp, _Proj>(__comp, __proj);
pair<_Iter, _Iter> __result(__first, __first); pair<_Iter, _Iter> __result(__first, __first);
@ -66,8 +65,8 @@ pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __c
if (__less(__first, __i)) { if (__less(__first, __i)) {
if (__less(__first, __result.first)) if (__less(__first, __result.first))
__result.first = __first; __result.first = __first;
if (!__less(__i, __result.second)) if (!__less(__i, __result.second))
__result.second = __i; __result.second = __i;
} else { } else {
if (__less(__i, __result.first)) if (__less(__i, __result.first))
__result.first = __i; __result.first = __i;
@ -80,21 +79,21 @@ pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __c
} }
template <class _ForwardIterator, class _Compare> template <class _ForwardIterator, class _Compare>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator>
pair<_ForwardIterator, _ForwardIterator>
minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
static_assert(__has_forward_iterator_category<_ForwardIterator>::value, static_assert(
"std::minmax_element requires a ForwardIterator"); __has_forward_iterator_category<_ForwardIterator>::value, "std::minmax_element requires a ForwardIterator");
static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, static_assert(
"The comparator has to be callable"); __is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, "The comparator has to be callable");
auto __proj = __identity(); auto __proj = __identity();
return std::__minmax_element_impl(__first, __last, __comp, __proj); return std::__minmax_element_impl(__first, __last, __comp, __proj);
} }
template <class _ForwardIterator> template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) { pair<_ForwardIterator, _ForwardIterator>
return std::minmax_element(__first, __last, __less<>()); minmax_element(_ForwardIterator __first, _ForwardIterator __last) {
return std::minmax_element(__first, __last, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -22,9 +22,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
_LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
for (; __first1 != __last1; ++__first1, (void)++__first2) for (; __first1 != __last1; ++__first1, (void)++__first2)
if (!__pred(*__first1, *__first2)) if (!__pred(*__first1, *__first2))
break; break;
@ -32,18 +31,19 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
} }
template <class _InputIterator1, class _InputIterator2> template <class _InputIterator1, class _InputIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
_LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
return std::mismatch(__first1, __last1, __first2, __equal_to()); return std::mismatch(__first1, __last1, __first2, __equal_to());
} }
#if _LIBCPP_STD_VER >= 14 #if _LIBCPP_STD_VER >= 14
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
_LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1,
mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _InputIterator1 __last1,
_BinaryPredicate __pred) { _InputIterator2 __first2,
_InputIterator2 __last2,
_BinaryPredicate __pred) {
for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
if (!__pred(*__first1, *__first2)) if (!__pred(*__first1, *__first2))
break; break;
@ -51,9 +51,8 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
} }
template <class _InputIterator1, class _InputIterator2> template <class _InputIterator1, class _InputIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
_LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
return std::mismatch(__first1, __last1, __first2, __last2, __equal_to()); return std::mismatch(__first1, __last1, __first2, __last2, __equal_to());
} }
#endif #endif

View File

@ -99,8 +99,7 @@ struct __move_loop {
struct __move_trivial { struct __move_trivial {
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
template <class _In, class _Out, template <class _In, class _Out, __enable_if_t<__can_lower_move_assignment_to_memmove<_In, _Out>::value, int> = 0>
__enable_if_t<__can_lower_move_assignment_to_memmove<_In, _Out>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
operator()(_In* __first, _In* __last, _Out* __result) const { operator()(_In* __first, _In* __last, _Out* __result) const {
return std::__copy_trivial_impl(__first, __last, __result); return std::__copy_trivial_impl(__first, __last, __result);

View File

@ -108,8 +108,7 @@ struct __move_backward_loop {
struct __move_backward_trivial { struct __move_backward_trivial {
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
template <class _In, class _Out, template <class _In, class _Out, __enable_if_t<__can_lower_move_assignment_to_memmove<_In, _Out>::value, int> = 0>
__enable_if_t<__can_lower_move_assignment_to_memmove<_In, _Out>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
operator()(_In* __first, _In* __last, _Out* __result) const { operator()(_In* __first, _In* __last, _Out* __result) const {
return std::__copy_backward_trivial_impl(__first, __last, __result); return std::__copy_backward_trivial_impl(__first, __last, __result);
@ -120,7 +119,8 @@ template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, clas
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) { __move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) {
static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value && static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value &&
std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible."); std::is_copy_constructible<_BidirectionalIterator1>::value,
"Iterators must be copy constructible.");
return std::__dispatch_copy_or_move<_AlgPolicy, __move_backward_loop<_AlgPolicy>, __move_backward_trivial>( return std::__dispatch_copy_or_move<_AlgPolicy, __move_backward_loop<_AlgPolicy>, __move_backward_trivial>(
std::move(__first), std::move(__last), std::move(__result)); std::move(__first), std::move(__last), std::move(__result));

View File

@ -26,50 +26,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator, class _Sentinel> template <class _AlgPolicy, class _Compare, class _BidirectionalIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool>
__next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) __next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) {
{ using _Result = pair<_BidirectionalIterator, bool>;
using _Result = pair<_BidirectionalIterator, bool>;
_BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
_BidirectionalIterator __i = __last_iter; _BidirectionalIterator __i = __last_iter;
if (__first == __last || __first == --__i) if (__first == __last || __first == --__i)
return _Result(std::move(__last_iter), false); return _Result(std::move(__last_iter), false);
while (true) while (true) {
{ _BidirectionalIterator __ip1 = __i;
_BidirectionalIterator __ip1 = __i; if (__comp(*--__i, *__ip1)) {
if (__comp(*--__i, *__ip1)) _BidirectionalIterator __j = __last_iter;
{ while (!__comp(*__i, *--__j))
_BidirectionalIterator __j = __last_iter; ;
while (!__comp(*__i, *--__j)) _IterOps<_AlgPolicy>::iter_swap(__i, __j);
; std::__reverse<_AlgPolicy>(__ip1, __last_iter);
_IterOps<_AlgPolicy>::iter_swap(__i, __j); return _Result(std::move(__last_iter), true);
std::__reverse<_AlgPolicy>(__ip1, __last_iter);
return _Result(std::move(__last_iter), true);
}
if (__i == __first)
{
std::__reverse<_AlgPolicy>(__first, __last_iter);
return _Result(std::move(__last_iter), false);
}
} }
if (__i == __first) {
std::__reverse<_AlgPolicy>(__first, __last_iter);
return _Result(std::move(__last_iter), false);
}
}
} }
template <class _BidirectionalIterator, class _Compare> template <class _BidirectionalIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
bool next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
{
return std::__next_permutation<_ClassicAlgPolicy>( return std::__next_permutation<_ClassicAlgPolicy>(
std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second; std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp))
.second;
} }
template <class _BidirectionalIterator> template <class _BidirectionalIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
bool next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) {
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) return std::next_permutation(__first, __last, __less<>());
{
return std::next_permutation(__first, __last, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -25,224 +25,207 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template<class _Compare, class _RandomAccessIterator> template <class _Compare, class _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool __nth_element_find_guard(
__nth_element_find_guard(_RandomAccessIterator& __i, _RandomAccessIterator& __j, _RandomAccessIterator& __i, _RandomAccessIterator& __j, _RandomAccessIterator __m, _Compare __comp) {
_RandomAccessIterator __m, _Compare __comp) // manually guard downward moving __j against __i
{ while (true) {
// manually guard downward moving __j against __i if (__i == --__j) {
while (true) { return false;
if (__i == --__j) {
return false;
}
if (__comp(*__j, *__m)) {
return true; // found guard for downward moving __j, now use unguarded partition
}
} }
if (__comp(*__j, *__m)) {
return true; // found guard for downward moving __j, now use unguarded partition
}
}
} }
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
// NOLINTNEXTLINE(readability-function-cognitive-complexity) // NOLINTNEXTLINE(readability-function-cognitive-complexity)
__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) __nth_element(
{ _RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) {
using _Ops = _IterOps<_AlgPolicy>; using _Ops = _IterOps<_AlgPolicy>;
// _Compare is known to be a reference type // _Compare is known to be a reference type
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
const difference_type __limit = 7; const difference_type __limit = 7;
while (true) while (true) {
{ if (__nth == __last)
if (__nth == __last) return;
return; difference_type __len = __last - __first;
difference_type __len = __last - __first; switch (__len) {
switch (__len) case 0:
{ case 1:
case 0: return;
case 1: case 2:
return; if (__comp(*--__last, *__first))
case 2: _Ops::iter_swap(__first, __last);
if (__comp(*--__last, *__first)) return;
_Ops::iter_swap(__first, __last); case 3: {
return; _RandomAccessIterator __m = __first;
case 3: std::__sort3<_AlgPolicy, _Compare>(__first, ++__m, --__last, __comp);
{ return;
_RandomAccessIterator __m = __first;
std::__sort3<_AlgPolicy, _Compare>(__first, ++__m, --__last, __comp);
return;
}
}
if (__len <= __limit)
{
std::__selection_sort<_AlgPolicy, _Compare>(__first, __last, __comp);
return;
}
// __len > __limit >= 3
_RandomAccessIterator __m = __first + __len/2;
_RandomAccessIterator __lm1 = __last;
unsigned __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, --__lm1, __comp);
// *__m is median
// partition [__first, __m) < *__m and *__m <= [__m, __last)
// (this inhibits tossing elements equivalent to __m around unnecessarily)
_RandomAccessIterator __i = __first;
_RandomAccessIterator __j = __lm1;
// j points beyond range to be tested, *__lm1 is known to be <= *__m
// The search going up is known to be guarded but the search coming down isn't.
// Prime the downward search with a guard.
if (!__comp(*__i, *__m)) // if *__first == *__m
{
// *__first == *__m, *__first doesn't go in first part
if (std::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) {
_Ops::iter_swap(__i, __j);
++__n_swaps;
} else {
// *__first == *__m, *__m <= all other elements
// Partition instead into [__first, __i) == *__first and *__first < [__i, __last)
++__i; // __first + 1
__j = __last;
if (!__comp(*__first, *--__j)) { // we need a guard if *__first == *(__last-1)
while (true) {
if (__i == __j) {
return; // [__first, __last) all equivalent elements
} else if (__comp(*__first, *__i)) {
_Ops::iter_swap(__i, __j);
++__n_swaps;
++__i;
break;
}
++__i;
}
}
// [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
if (__i == __j) {
return;
}
while (true) {
while (!__comp(*__first, *__i)) {
++__i;
_LIBCPP_ASSERT_UNCATEGORIZED(
__i != __last,
"Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
}
do {
_LIBCPP_ASSERT_UNCATEGORIZED(
__j != __first,
"Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
--__j;
} while (__comp(*__first, *__j));
if (__i >= __j)
break;
_Ops::iter_swap(__i, __j);
++__n_swaps;
++__i;
}
// [__first, __i) == *__first and *__first < [__i, __last)
// The first part is sorted,
if (__nth < __i) {
return;
}
// __nth_element the second part
// std::__nth_element<_Compare>(__i, __nth, __last, __comp);
__first = __i;
continue;
}
}
++__i;
// j points beyond range to be tested, *__lm1 is known to be <= *__m
// if not yet partitioned...
if (__i < __j)
{
// known that *(__i - 1) < *__m
while (true)
{
// __m still guards upward moving __i
while (__comp(*__i, *__m)) {
++__i;
_LIBCPP_ASSERT_UNCATEGORIZED(
__i != __last,
"Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
}
// It is now known that a guard exists for downward moving __j
do {
_LIBCPP_ASSERT_UNCATEGORIZED(
__j != __first,
"Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
--__j;
} while (!__comp(*__j, *__m));
if (__i >= __j)
break;
_Ops::iter_swap(__i, __j);
++__n_swaps;
// It is known that __m != __j
// If __m just moved, follow it
if (__m == __i)
__m = __j;
++__i;
}
}
// [__first, __i) < *__m and *__m <= [__i, __last)
if (__i != __m && __comp(*__m, *__i))
{
_Ops::iter_swap(__i, __m);
++__n_swaps;
}
// [__first, __i) < *__i and *__i <= [__i+1, __last)
if (__nth == __i)
return;
if (__n_swaps == 0)
{
// We were given a perfectly partitioned sequence. Coincidence?
if (__nth < __i)
{
// Check for [__first, __i) already sorted
__j = __m = __first;
while (true) {
if (++__j == __i) {
// [__first, __i) sorted
return;
}
if (__comp(*__j, *__m)) {
// not yet sorted, so sort
break;
}
__m = __j;
}
}
else
{
// Check for [__i, __last) already sorted
__j = __m = __i;
while (true) {
if (++__j == __last) {
// [__i, __last) sorted
return;
}
if (__comp(*__j, *__m)) {
// not yet sorted, so sort
break;
}
__m = __j;
}
}
}
// __nth_element on range containing __nth
if (__nth < __i)
{
// std::__nth_element<_Compare>(__first, __nth, __i, __comp);
__last = __i;
}
else
{
// std::__nth_element<_Compare>(__i+1, __nth, __last, __comp);
__first = ++__i;
}
} }
}
if (__len <= __limit) {
std::__selection_sort<_AlgPolicy, _Compare>(__first, __last, __comp);
return;
}
// __len > __limit >= 3
_RandomAccessIterator __m = __first + __len / 2;
_RandomAccessIterator __lm1 = __last;
unsigned __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, --__lm1, __comp);
// *__m is median
// partition [__first, __m) < *__m and *__m <= [__m, __last)
// (this inhibits tossing elements equivalent to __m around unnecessarily)
_RandomAccessIterator __i = __first;
_RandomAccessIterator __j = __lm1;
// j points beyond range to be tested, *__lm1 is known to be <= *__m
// The search going up is known to be guarded but the search coming down isn't.
// Prime the downward search with a guard.
if (!__comp(*__i, *__m)) // if *__first == *__m
{
// *__first == *__m, *__first doesn't go in first part
if (std::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) {
_Ops::iter_swap(__i, __j);
++__n_swaps;
} else {
// *__first == *__m, *__m <= all other elements
// Partition instead into [__first, __i) == *__first and *__first < [__i, __last)
++__i; // __first + 1
__j = __last;
if (!__comp(*__first, *--__j)) { // we need a guard if *__first == *(__last-1)
while (true) {
if (__i == __j) {
return; // [__first, __last) all equivalent elements
} else if (__comp(*__first, *__i)) {
_Ops::iter_swap(__i, __j);
++__n_swaps;
++__i;
break;
}
++__i;
}
}
// [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
if (__i == __j) {
return;
}
while (true) {
while (!__comp(*__first, *__i)) {
++__i;
_LIBCPP_ASSERT_UNCATEGORIZED(
__i != __last,
"Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
}
do {
_LIBCPP_ASSERT_UNCATEGORIZED(
__j != __first,
"Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
--__j;
} while (__comp(*__first, *__j));
if (__i >= __j)
break;
_Ops::iter_swap(__i, __j);
++__n_swaps;
++__i;
}
// [__first, __i) == *__first and *__first < [__i, __last)
// The first part is sorted,
if (__nth < __i) {
return;
}
// __nth_element the second part
// std::__nth_element<_Compare>(__i, __nth, __last, __comp);
__first = __i;
continue;
}
}
++__i;
// j points beyond range to be tested, *__lm1 is known to be <= *__m
// if not yet partitioned...
if (__i < __j) {
// known that *(__i - 1) < *__m
while (true) {
// __m still guards upward moving __i
while (__comp(*__i, *__m)) {
++__i;
_LIBCPP_ASSERT_UNCATEGORIZED(
__i != __last,
"Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
}
// It is now known that a guard exists for downward moving __j
do {
_LIBCPP_ASSERT_UNCATEGORIZED(
__j != __first,
"Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
--__j;
} while (!__comp(*__j, *__m));
if (__i >= __j)
break;
_Ops::iter_swap(__i, __j);
++__n_swaps;
// It is known that __m != __j
// If __m just moved, follow it
if (__m == __i)
__m = __j;
++__i;
}
}
// [__first, __i) < *__m and *__m <= [__i, __last)
if (__i != __m && __comp(*__m, *__i)) {
_Ops::iter_swap(__i, __m);
++__n_swaps;
}
// [__first, __i) < *__i and *__i <= [__i+1, __last)
if (__nth == __i)
return;
if (__n_swaps == 0) {
// We were given a perfectly partitioned sequence. Coincidence?
if (__nth < __i) {
// Check for [__first, __i) already sorted
__j = __m = __first;
while (true) {
if (++__j == __i) {
// [__first, __i) sorted
return;
}
if (__comp(*__j, *__m)) {
// not yet sorted, so sort
break;
}
__m = __j;
}
} else {
// Check for [__i, __last) already sorted
__j = __m = __i;
while (true) {
if (++__j == __last) {
// [__i, __last) sorted
return;
}
if (__comp(*__j, *__m)) {
// not yet sorted, so sort
break;
}
__m = __j;
}
}
}
// __nth_element on range containing __nth
if (__nth < __i) {
// std::__nth_element<_Compare>(__first, __nth, __i, __comp);
__last = __i;
} else {
// std::__nth_element<_Compare>(__i+1, __nth, __last, __comp);
__first = ++__i;
}
}
} }
template <class _AlgPolicy, class _RandomAccessIterator, class _Compare> template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __nth_element_impl(
void __nth_element_impl(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare& __comp) {
_Compare& __comp) {
if (__nth == __last) if (__nth == __last)
return; return;
@ -257,15 +240,14 @@ void __nth_element_impl(_RandomAccessIterator __first, _RandomAccessIterator __n
} }
template <class _RandomAccessIterator, class _Compare> template <class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) {
_Compare __comp) {
std::__nth_element_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__nth), std::move(__last), __comp); std::__nth_element_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__nth), std::move(__last), __comp);
} }
template <class _RandomAccessIterator> template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) { nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) {
std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<>()); std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<>());
} }

View File

@ -29,8 +29,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator __partial_sort_impl(
_RandomAccessIterator __partial_sort_impl(
_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare&& __comp) { _RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare&& __comp) {
if (__first == __middle) { if (__first == __middle) {
return _IterOps<_AlgPolicy>::next(__middle, __last); return _IterOps<_AlgPolicy>::next(__middle, __last);
@ -39,14 +38,12 @@ _RandomAccessIterator __partial_sort_impl(
std::__make_heap<_AlgPolicy>(__first, __middle, __comp); std::__make_heap<_AlgPolicy>(__first, __middle, __comp);
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;
_RandomAccessIterator __i = __middle; _RandomAccessIterator __i = __middle;
for (; __i != __last; ++__i) for (; __i != __last; ++__i) {
{ if (__comp(*__i, *__first)) {
if (__comp(*__i, *__first)) _IterOps<_AlgPolicy>::iter_swap(__i, __first);
{ std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first);
_IterOps<_AlgPolicy>::iter_swap(__i, __first); }
std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first);
}
} }
std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp); std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp);
@ -54,11 +51,10 @@ _RandomAccessIterator __partial_sort_impl(
} }
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
_RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare& __comp) {
_Compare& __comp) {
if (__first == __middle) if (__first == __middle)
return _IterOps<_AlgPolicy>::next(__middle, __last); return _IterOps<_AlgPolicy>::next(__middle, __last);
std::__debug_randomize_range<_AlgPolicy>(__first, __last); std::__debug_randomize_range<_AlgPolicy>(__first, __last);
@ -71,11 +67,8 @@ _RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAcces
} }
template <class _RandomAccessIterator, class _Compare> template <class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void partial_sort(
void _RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) {
partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
_Compare __comp)
{
static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible.");
static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable.");
@ -83,11 +76,9 @@ partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Ran
} }
template <class _RandomAccessIterator> template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) {
partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) std::partial_sort(__first, __middle, __last, __less<>());
{
std::partial_sort(__first, __middle, __last, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -30,56 +30,70 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Compare, template <class _AlgPolicy,
class _InputIterator, class _Sentinel1, class _RandomAccessIterator, class _Sentinel2, class _Compare,
class _Proj1, class _Proj2> class _InputIterator,
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _RandomAccessIterator> class _Sentinel1,
__partial_sort_copy(_InputIterator __first, _Sentinel1 __last, class _RandomAccessIterator,
_RandomAccessIterator __result_first, _Sentinel2 __result_last, class _Sentinel2,
_Compare&& __comp, _Proj1&& __proj1, _Proj2&& __proj2) class _Proj1,
{ class _Proj2>
_RandomAccessIterator __r = __result_first; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _RandomAccessIterator> __partial_sort_copy(
auto&& __projected_comp = std::__make_projected(__comp, __proj2); _InputIterator __first,
_Sentinel1 __last,
_RandomAccessIterator __result_first,
_Sentinel2 __result_last,
_Compare&& __comp,
_Proj1&& __proj1,
_Proj2&& __proj2) {
_RandomAccessIterator __r = __result_first;
auto&& __projected_comp = std::__make_projected(__comp, __proj2);
if (__r != __result_last) if (__r != __result_last) {
{ for (; __first != __last && __r != __result_last; ++__first, (void)++__r)
for (; __first != __last && __r != __result_last; ++__first, (void) ++__r) *__r = *__first;
*__r = *__first; std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp); typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first;
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; for (; __first != __last; ++__first)
for (; __first != __last; ++__first) if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) {
if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) { *__result_first = *__first;
*__result_first = *__first; std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first);
std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first); }
} std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp); }
}
return pair<_InputIterator, _RandomAccessIterator>( return pair<_InputIterator, _RandomAccessIterator>(
_IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r)); _IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r));
} }
template <class _InputIterator, class _RandomAccessIterator, class _Compare> template <class _InputIterator, class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator partial_sort_copy(
_RandomAccessIterator _InputIterator __first,
partial_sort_copy(_InputIterator __first, _InputIterator __last, _InputIterator __last,
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) _RandomAccessIterator __result_first,
{ _RandomAccessIterator __result_last,
static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value, _Compare __comp) {
"Comparator has to be callable"); static_assert(
__is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value, "Comparator has to be callable");
auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>(__first, __last, __result_first, __result_last, auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>(
static_cast<__comp_ref_type<_Compare> >(__comp), __identity(), __identity()); __first,
__last,
__result_first,
__result_last,
static_cast<__comp_ref_type<_Compare> >(__comp),
__identity(),
__identity());
return __result.second; return __result.second;
} }
template <class _InputIterator, class _RandomAccessIterator> template <class _InputIterator, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator partial_sort_copy(
_RandomAccessIterator _InputIterator __first,
partial_sort_copy(_InputIterator __first, _InputIterator __last, _InputIterator __last,
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last) _RandomAccessIterator __result_first,
{ _RandomAccessIterator __result_last) {
return std::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>()); return std::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -23,70 +23,58 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Predicate, class _AlgPolicy, class _ForwardIterator, class _Sentinel> template <class _Predicate, class _AlgPolicy, class _ForwardIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
__partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) __partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) {
{ while (true) {
while (true) if (__first == __last)
{ return std::make_pair(std::move(__first), std::move(__first));
if (__first == __last) if (!__pred(*__first))
return std::make_pair(std::move(__first), std::move(__first)); break;
if (!__pred(*__first)) ++__first;
break; }
++__first;
}
_ForwardIterator __p = __first; _ForwardIterator __p = __first;
while (++__p != __last) while (++__p != __last) {
{ if (__pred(*__p)) {
if (__pred(*__p)) _IterOps<_AlgPolicy>::iter_swap(__first, __p);
{ ++__first;
_IterOps<_AlgPolicy>::iter_swap(__first, __p);
++__first;
}
} }
return std::make_pair(std::move(__first), std::move(__p)); }
return std::make_pair(std::move(__first), std::move(__p));
} }
template <class _Predicate, class _AlgPolicy, class _BidirectionalIterator, class _Sentinel> template <class _Predicate, class _AlgPolicy, class _BidirectionalIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, _BidirectionalIterator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, _BidirectionalIterator>
__partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred, __partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred, bidirectional_iterator_tag) {
bidirectional_iterator_tag) _BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel);
{ _BidirectionalIterator __last = __original_last;
_BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel);
_BidirectionalIterator __last = __original_last;
while (true) while (true) {
{ while (true) {
while (true) if (__first == __last)
{ return std::make_pair(std::move(__first), std::move(__original_last));
if (__first == __last) if (!__pred(*__first))
return std::make_pair(std::move(__first), std::move(__original_last)); break;
if (!__pred(*__first)) ++__first;
break;
++__first;
}
do
{
if (__first == --__last)
return std::make_pair(std::move(__first), std::move(__original_last));
} while (!__pred(*__last));
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
++__first;
} }
do {
if (__first == --__last)
return std::make_pair(std::move(__first), std::move(__original_last));
} while (!__pred(*__last));
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
++__first;
}
} }
template <class _AlgPolicy, class _ForwardIterator, class _Sentinel, class _Predicate, class _IterCategory> template <class _AlgPolicy, class _ForwardIterator, class _Sentinel, class _Predicate, class _IterCategory>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
pair<_ForwardIterator, _ForwardIterator> __partition( __partition(_ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) {
_ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) {
return std::__partition_impl<__remove_cvref_t<_Predicate>&, _AlgPolicy>( return std::__partition_impl<__remove_cvref_t<_Predicate>&, _AlgPolicy>(
std::move(__first), std::move(__last), __pred, __iter_category); std::move(__first), std::move(__last), __pred, __iter_category);
} }
template <class _ForwardIterator, class _Predicate> template <class _ForwardIterator, class _Predicate>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
_ForwardIterator partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
{
using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category;
auto __result = std::__partition<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred, _IterCategory()); auto __result = std::__partition<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred, _IterCategory());
return __result.first; return __result.first;

View File

@ -19,27 +19,23 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _OutputIterator1, template <class _InputIterator, class _OutputIterator1, class _OutputIterator2, class _Predicate>
class _OutputIterator2, class _Predicate> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_OutputIterator1, _OutputIterator2> partition_copy(
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_OutputIterator1, _OutputIterator2> _InputIterator __first,
partition_copy(_InputIterator __first, _InputIterator __last, _InputIterator __last,
_OutputIterator1 __out_true, _OutputIterator2 __out_false, _OutputIterator1 __out_true,
_Predicate __pred) _OutputIterator2 __out_false,
{ _Predicate __pred) {
for (; __first != __last; ++__first) for (; __first != __last; ++__first) {
{ if (__pred(*__first)) {
if (__pred(*__first)) *__out_true = *__first;
{ ++__out_true;
*__out_true = *__first; } else {
++__out_true; *__out_false = *__first;
} ++__out_false;
else
{
*__out_false = *__first;
++__out_false;
}
} }
return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); }
return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false);
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -21,26 +21,22 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template<class _ForwardIterator, class _Predicate> template <class _ForwardIterator, class _Predicate>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
{ typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; difference_type __len = std::distance(__first, __last);
difference_type __len = std::distance(__first, __last); while (__len != 0) {
while (__len != 0) difference_type __l2 = std::__half_positive(__len);
{ _ForwardIterator __m = __first;
difference_type __l2 = std::__half_positive(__len); std::advance(__m, __l2);
_ForwardIterator __m = __first; if (__pred(*__m)) {
std::advance(__m, __l2); __first = ++__m;
if (__pred(*__m)) __len -= __l2 + 1;
{ } else
__first = ++__m; __len = __l2;
__len -= __l2 + 1; }
} return __first;
else
__len = __l2;
}
return __first;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -31,16 +31,18 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp, __pop_heap(_RandomAccessIterator __first,
typename iterator_traits<_RandomAccessIterator>::difference_type __len) { _RandomAccessIterator __last,
_Compare& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
_LIBCPP_ASSERT_UNCATEGORIZED(__len > 0, "The heap given to pop_heap must be non-empty"); _LIBCPP_ASSERT_UNCATEGORIZED(__len > 0, "The heap given to pop_heap must be non-empty");
__comp_ref_type<_Compare> __comp_ref = __comp; __comp_ref_type<_Compare> __comp_ref = __comp;
using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
if (__len > 1) { if (__len > 1) {
value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first
_RandomAccessIterator __hole = std::__floyd_sift_down<_AlgPolicy>(__first, __comp_ref, __len); _RandomAccessIterator __hole = std::__floyd_sift_down<_AlgPolicy>(__first, __comp_ref, __len);
--__last; --__last;
@ -56,8 +58,8 @@ void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co
} }
template <class _RandomAccessIterator, class _Compare> template <class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible.");
static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable.");
@ -66,8 +68,8 @@ void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp
} }
template <class _RandomAccessIterator> template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::pop_heap(std::move(__first), std::move(__last), __less<>()); std::pop_heap(std::move(__first), std::move(__last), __less<>());
} }

View File

@ -25,52 +25,44 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator, class _Sentinel> template <class _AlgPolicy, class _Compare, class _BidirectionalIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool>
pair<_BidirectionalIterator, bool> __prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) {
__prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) using _Result = pair<_BidirectionalIterator, bool>;
{
using _Result = pair<_BidirectionalIterator, bool>;
_BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
_BidirectionalIterator __i = __last_iter; _BidirectionalIterator __i = __last_iter;
if (__first == __last || __first == --__i) if (__first == __last || __first == --__i)
return _Result(std::move(__last_iter), false); return _Result(std::move(__last_iter), false);
while (true) while (true) {
{ _BidirectionalIterator __ip1 = __i;
_BidirectionalIterator __ip1 = __i; if (__comp(*__ip1, *--__i)) {
if (__comp(*__ip1, *--__i)) _BidirectionalIterator __j = __last_iter;
{ while (!__comp(*--__j, *__i))
_BidirectionalIterator __j = __last_iter; ;
while (!__comp(*--__j, *__i)) _IterOps<_AlgPolicy>::iter_swap(__i, __j);
; std::__reverse<_AlgPolicy>(__ip1, __last_iter);
_IterOps<_AlgPolicy>::iter_swap(__i, __j); return _Result(std::move(__last_iter), true);
std::__reverse<_AlgPolicy>(__ip1, __last_iter);
return _Result(std::move(__last_iter), true);
}
if (__i == __first)
{
std::__reverse<_AlgPolicy>(__first, __last_iter);
return _Result(std::move(__last_iter), false);
}
} }
if (__i == __first) {
std::__reverse<_AlgPolicy>(__first, __last_iter);
return _Result(std::move(__last_iter), false);
}
}
} }
template <class _BidirectionalIterator, class _Compare> template <class _BidirectionalIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
bool prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
{
return std::__prev_permutation<_ClassicAlgPolicy>( return std::__prev_permutation<_ClassicAlgPolicy>(
std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second; std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp))
.second;
} }
template <class _BidirectionalIterator> template <class _BidirectionalIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
bool prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) {
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) return std::prev_permutation(__first, __last, __less<>());
{
return std::prev_permutation(__first, __last, __less<>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -28,20 +28,22 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp, __sift_up(_RandomAccessIterator __first,
typename iterator_traits<_RandomAccessIterator>::difference_type __len) { _RandomAccessIterator __last,
_Compare&& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
if (__len > 1) { if (__len > 1) {
__len = (__len - 2) / 2; __len = (__len - 2) / 2;
_RandomAccessIterator __ptr = __first + __len; _RandomAccessIterator __ptr = __first + __len;
if (__comp(*__ptr, *--__last)) { if (__comp(*__ptr, *--__last)) {
value_type __t(_IterOps<_AlgPolicy>::__iter_move(__last)); value_type __t(_IterOps<_AlgPolicy>::__iter_move(__last));
do { do {
*__last = _IterOps<_AlgPolicy>::__iter_move(__ptr); *__last = _IterOps<_AlgPolicy>::__iter_move(__ptr);
__last = __ptr; __last = __ptr;
if (__len == 0) if (__len == 0)
break; break;
__len = (__len - 1) / 2; __len = (__len - 1) / 2;
@ -54,15 +56,15 @@ void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
} }
template <class _AlgPolicy, class _RandomAccessIterator, class _Compare> template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
void __push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { __push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first; typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first;
std::__sift_up<_AlgPolicy, __comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp, __len); std::__sift_up<_AlgPolicy, __comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp, __len);
} }
template <class _RandomAccessIterator, class _Compare> template <class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible.");
static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable.");
@ -70,8 +72,8 @@ void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
} }
template <class _RandomAccessIterator> template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::push_heap(std::move(__first), std::move(__last), __less<>()); std::push_heap(std::move(__first), std::move(__last), __less<>());
} }

View File

@ -22,22 +22,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator, class _Tp> template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
{ __first = std::find(__first, __last, __value);
__first = std::find(__first, __last, __value); if (__first != __last) {
if (__first != __last) _ForwardIterator __i = __first;
{ while (++__i != __last) {
_ForwardIterator __i = __first; if (!(*__i == __value)) {
while (++__i != __last) *__first = std::move(*__i);
{ ++__first;
if (!(*__i == __value)) }
{
*__first = std::move(*__i);
++__first;
}
}
} }
return __first; }
return __first;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -18,19 +18,15 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _OutputIterator, class _Tp> template <class _InputIterator, class _OutputIterator, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
_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)) {
for (; __first != __last; ++__first) *__result = *__first;
{ ++__result;
if (!(*__first == __value))
{
*__result = *__first;
++__result;
}
} }
return __result; }
return __result;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -18,19 +18,15 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _OutputIterator, class _Predicate> template <class _InputIterator, class _OutputIterator, class _Predicate>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
_OutputIterator remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) {
remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) for (; __first != __last; ++__first) {
{ if (!__pred(*__first)) {
for (; __first != __last; ++__first) *__result = *__first;
{ ++__result;
if (!__pred(*__first))
{
*__result = *__first;
++__result;
}
} }
return __result; }
return __result;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -21,22 +21,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator, class _Predicate> template <class _ForwardIterator, class _Predicate>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
{ __first = std::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred);
__first = std::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred); if (__first != __last) {
if (__first != __last) _ForwardIterator __i = __first;
{ while (++__i != __last) {
_ForwardIterator __i = __first; if (!__pred(*__i)) {
while (++__i != __last) *__first = std::move(*__i);
{ ++__first;
if (!__pred(*__i)) }
{
*__first = std::move(*__i);
++__first;
}
}
} }
return __first; }
return __first;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -18,13 +18,11 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator, class _Tp> template <class _ForwardIterator, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) {
replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) for (; __first != __last; ++__first)
{ if (*__first == __old_value)
for (; __first != __last; ++__first) *__first = __new_value;
if (*__first == __old_value)
*__first = __new_value;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -18,17 +18,18 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _OutputIterator, class _Tp> template <class _InputIterator, class _OutputIterator, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator replace_copy(
_OutputIterator _InputIterator __first,
replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _InputIterator __last,
const _Tp& __old_value, const _Tp& __new_value) _OutputIterator __result,
{ const _Tp& __old_value,
for (; __first != __last; ++__first, (void) ++__result) const _Tp& __new_value) {
if (*__first == __old_value) for (; __first != __last; ++__first, (void)++__result)
*__result = __new_value; if (*__first == __old_value)
else *__result = __new_value;
*__result = *__first; else
return __result; *__result = *__first;
return __result;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -18,17 +18,18 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _OutputIterator, class _Predicate, class _Tp> template <class _InputIterator, class _OutputIterator, class _Predicate, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator replace_copy_if(
_OutputIterator _InputIterator __first,
replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _InputIterator __last,
_Predicate __pred, const _Tp& __new_value) _OutputIterator __result,
{ _Predicate __pred,
for (; __first != __last; ++__first, (void) ++__result) const _Tp& __new_value) {
if (__pred(*__first)) for (; __first != __last; ++__first, (void)++__result)
*__result = __new_value; if (__pred(*__first))
else *__result = __new_value;
*__result = *__first; else
return __result; *__result = *__first;
return __result;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -18,13 +18,11 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator, class _Predicate, class _Tp> template <class _ForwardIterator, class _Predicate, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) {
replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) for (; __first != __last; ++__first)
{ if (__pred(*__first))
for (; __first != __last; ++__first) *__first = __new_value;
if (__pred(*__first))
*__first = __new_value;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -22,41 +22,33 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _BidirectionalIterator> template <class _AlgPolicy, class _BidirectionalIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void __reverse_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) {
__reverse_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) while (__first != __last) {
{ if (__first == --__last)
while (__first != __last) break;
{ _IterOps<_AlgPolicy>::iter_swap(__first, __last);
if (__first == --__last) ++__first;
break; }
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
++__first;
}
} }
template <class _AlgPolicy, class _RandomAccessIterator> template <class _AlgPolicy, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void __reverse_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) {
__reverse_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) if (__first != __last)
{ for (; __first < --__last; ++__first)
if (__first != __last) _IterOps<_AlgPolicy>::iter_swap(__first, __last);
for (; __first < --__last; ++__first)
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
} }
template <class _AlgPolicy, class _BidirectionalIterator, class _Sentinel> template <class _AlgPolicy, class _BidirectionalIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __reverse(_BidirectionalIterator __first, _Sentinel __last) {
void __reverse(_BidirectionalIterator __first, _Sentinel __last) {
using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_BidirectionalIterator>; using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_BidirectionalIterator>;
std::__reverse_impl<_AlgPolicy>(std::move(__first), std::move(__last), _IterCategory()); std::__reverse_impl<_AlgPolicy>(std::move(__first), std::move(__last), _IterCategory());
} }
template <class _BidirectionalIterator> template <class _BidirectionalIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) {
reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
{
std::__reverse<_ClassicAlgPolicy>(std::move(__first), std::move(__last)); std::__reverse<_ClassicAlgPolicy>(std::move(__first), std::move(__last));
} }

View File

@ -18,13 +18,11 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _BidirectionalIterator, class _OutputIterator> template <class _BidirectionalIterator, class _OutputIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
_OutputIterator reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) {
reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) for (; __first != __last; ++__result)
{ *__result = *--__last;
for (; __first != __last; ++__result) return __result;
*__result = *--__last;
return __result;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -27,193 +27,165 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _ForwardIterator> template <class _AlgPolicy, class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
__rotate_left(_ForwardIterator __first, _ForwardIterator __last) __rotate_left(_ForwardIterator __first, _ForwardIterator __last) {
{ typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
typedef typename iterator_traits<_ForwardIterator>::value_type value_type; using _Ops = _IterOps<_AlgPolicy>;
using _Ops = _IterOps<_AlgPolicy>;
value_type __tmp = _Ops::__iter_move(__first); value_type __tmp = _Ops::__iter_move(__first);
_ForwardIterator __lm1 = std::__move<_AlgPolicy>( _ForwardIterator __lm1 = std::__move<_AlgPolicy>(_Ops::next(__first), __last, __first).second;
_Ops::next(__first), __last, __first).second; *__lm1 = std::move(__tmp);
*__lm1 = std::move(__tmp); return __lm1;
return __lm1;
} }
template <class _AlgPolicy, class _BidirectionalIterator> template <class _AlgPolicy, class _BidirectionalIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator
__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) __rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) {
{ typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; using _Ops = _IterOps<_AlgPolicy>;
using _Ops = _IterOps<_AlgPolicy>;
_BidirectionalIterator __lm1 = _Ops::prev(__last); _BidirectionalIterator __lm1 = _Ops::prev(__last);
value_type __tmp = _Ops::__iter_move(__lm1); value_type __tmp = _Ops::__iter_move(__lm1);
_BidirectionalIterator __fp1 = std::__move_backward<_AlgPolicy>(__first, __lm1, std::move(__last)).second; _BidirectionalIterator __fp1 = std::__move_backward<_AlgPolicy>(__first, __lm1, std::move(__last)).second;
*__first = std::move(__tmp); *__first = std::move(__tmp);
return __fp1; return __fp1;
} }
template <class _AlgPolicy, class _ForwardIterator> template <class _AlgPolicy, class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _ForwardIterator _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _ForwardIterator
__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) __rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) {
{ _ForwardIterator __i = __middle;
_ForwardIterator __i = __middle; while (true) {
while (true) _IterOps<_AlgPolicy>::iter_swap(__first, __i);
{ ++__first;
_IterOps<_AlgPolicy>::iter_swap(__first, __i); if (++__i == __last)
++__first; break;
if (++__i == __last) if (__first == __middle)
break; __middle = __i;
}
_ForwardIterator __r = __first;
if (__first != __middle) {
__i = __middle;
while (true) {
_IterOps<_AlgPolicy>::iter_swap(__first, __i);
++__first;
if (++__i == __last) {
if (__first == __middle) if (__first == __middle)
__middle = __i; break;
}
_ForwardIterator __r = __first;
if (__first != __middle)
{
__i = __middle; __i = __middle;
while (true) } else if (__first == __middle)
{ __middle = __i;
_IterOps<_AlgPolicy>::iter_swap(__first, __i);
++__first;
if (++__i == __last)
{
if (__first == __middle)
break;
__i = __middle;
}
else if (__first == __middle)
__middle = __i;
}
} }
return __r; }
return __r;
} }
template<typename _Integral> template <typename _Integral>
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral __algo_gcd(_Integral __x, _Integral __y) {
_LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral do {
__algo_gcd(_Integral __x, _Integral __y) _Integral __t = __x % __y;
{ __x = __y;
do __y = __t;
{ } while (__y);
_Integral __t = __x % __y; return __x;
__x = __y;
__y = __t;
} while (__y);
return __x;
} }
template <class _AlgPolicy, typename _RandomAccessIterator> template <class _AlgPolicy, typename _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _RandomAccessIterator _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _RandomAccessIterator
__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) __rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) {
{ typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; using _Ops = _IterOps<_AlgPolicy>;
using _Ops = _IterOps<_AlgPolicy>;
const difference_type __m1 = __middle - __first; const difference_type __m1 = __middle - __first;
const difference_type __m2 = _Ops::distance(__middle, __last); const difference_type __m2 = _Ops::distance(__middle, __last);
if (__m1 == __m2) if (__m1 == __m2) {
{ std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last);
std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last); return __middle;
return __middle; }
} const difference_type __g = std::__algo_gcd(__m1, __m2);
const difference_type __g = std::__algo_gcd(__m1, __m2); for (_RandomAccessIterator __p = __first + __g; __p != __first;) {
for (_RandomAccessIterator __p = __first + __g; __p != __first;) value_type __t(_Ops::__iter_move(--__p));
{ _RandomAccessIterator __p1 = __p;
value_type __t(_Ops::__iter_move(--__p)); _RandomAccessIterator __p2 = __p1 + __m1;
_RandomAccessIterator __p1 = __p; do {
_RandomAccessIterator __p2 = __p1 + __m1; *__p1 = _Ops::__iter_move(__p2);
do __p1 = __p2;
{ const difference_type __d = _Ops::distance(__p2, __last);
*__p1 = _Ops::__iter_move(__p2); if (__m1 < __d)
__p1 = __p2; __p2 += __m1;
const difference_type __d = _Ops::distance(__p2, __last); else
if (__m1 < __d) __p2 = __first + (__m1 - __d);
__p2 += __m1; } while (__p2 != __p);
else *__p1 = std::move(__t);
__p2 = __first + (__m1 - __d); }
} while (__p2 != __p); return __first + __m2;
*__p1 = std::move(__t);
}
return __first + __m2;
} }
template <class _AlgPolicy, class _ForwardIterator> template <class _AlgPolicy, class _ForwardIterator>
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
_LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator __rotate_impl(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, std::forward_iterator_tag) {
__rotate_impl(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
std::forward_iterator_tag) if (is_trivially_move_assignable<value_type>::value) {
{ if (_IterOps<_AlgPolicy>::next(__first) == __middle)
typedef typename iterator_traits<_ForwardIterator>::value_type value_type; return std::__rotate_left<_AlgPolicy>(__first, __last);
if (is_trivially_move_assignable<value_type>::value) }
{ return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
if (_IterOps<_AlgPolicy>::next(__first) == __middle)
return std::__rotate_left<_AlgPolicy>(__first, __last);
}
return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
} }
template <class _AlgPolicy, class _BidirectionalIterator> template <class _AlgPolicy, class _BidirectionalIterator>
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator __rotate_impl(
_LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator _BidirectionalIterator __first,
__rotate_impl(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _BidirectionalIterator __middle,
bidirectional_iterator_tag) _BidirectionalIterator __last,
{ bidirectional_iterator_tag) {
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
if (is_trivially_move_assignable<value_type>::value) if (is_trivially_move_assignable<value_type>::value) {
{ if (_IterOps<_AlgPolicy>::next(__first) == __middle)
if (_IterOps<_AlgPolicy>::next(__first) == __middle) return std::__rotate_left<_AlgPolicy>(__first, __last);
return std::__rotate_left<_AlgPolicy>(__first, __last); if (_IterOps<_AlgPolicy>::next(__middle) == __last)
if (_IterOps<_AlgPolicy>::next(__middle) == __last) return std::__rotate_right<_AlgPolicy>(__first, __last);
return std::__rotate_right<_AlgPolicy>(__first, __last); }
} return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
} }
template <class _AlgPolicy, class _RandomAccessIterator> template <class _AlgPolicy, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator __rotate_impl(
_LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator _RandomAccessIterator __first,
__rotate_impl(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _RandomAccessIterator __middle,
random_access_iterator_tag) _RandomAccessIterator __last,
{ random_access_iterator_tag) {
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
if (is_trivially_move_assignable<value_type>::value) if (is_trivially_move_assignable<value_type>::value) {
{ if (_IterOps<_AlgPolicy>::next(__first) == __middle)
if (_IterOps<_AlgPolicy>::next(__first) == __middle) return std::__rotate_left<_AlgPolicy>(__first, __last);
return std::__rotate_left<_AlgPolicy>(__first, __last); if (_IterOps<_AlgPolicy>::next(__middle) == __last)
if (_IterOps<_AlgPolicy>::next(__middle) == __last) return std::__rotate_right<_AlgPolicy>(__first, __last);
return std::__rotate_right<_AlgPolicy>(__first, __last); return std::__rotate_gcd<_AlgPolicy>(__first, __middle, __last);
return std::__rotate_gcd<_AlgPolicy>(__first, __middle, __last); }
} return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
} }
template <class _AlgPolicy, class _Iterator, class _Sentinel> template <class _AlgPolicy, class _Iterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iterator, _Iterator>
pair<_Iterator, _Iterator>
__rotate(_Iterator __first, _Iterator __middle, _Sentinel __last) { __rotate(_Iterator __first, _Iterator __middle, _Sentinel __last) {
using _Ret = pair<_Iterator, _Iterator>; using _Ret = pair<_Iterator, _Iterator>;
_Iterator __last_iter = _IterOps<_AlgPolicy>::next(__middle, __last); _Iterator __last_iter = _IterOps<_AlgPolicy>::next(__middle, __last);
if (__first == __middle) if (__first == __middle)
return _Ret(__last_iter, __last_iter); return _Ret(__last_iter, __last_iter);
if (__middle == __last) if (__middle == __last)
return _Ret(std::move(__first), std::move(__last_iter)); return _Ret(std::move(__first), std::move(__last_iter));
using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_Iterator>; using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_Iterator>;
auto __result = std::__rotate_impl<_AlgPolicy>( auto __result = std::__rotate_impl<_AlgPolicy>(std::move(__first), std::move(__middle), __last_iter, _IterCategory());
std::move(__first), std::move(__middle), __last_iter, _IterCategory());
return _Ret(std::move(__result), std::move(__last_iter)); return _Ret(std::move(__result), std::move(__last_iter));
} }
template <class _ForwardIterator> template <class _ForwardIterator>
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
_LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) {
rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) return std::__rotate<_ClassicAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last)).first;
{
return std::__rotate<_ClassicAlgPolicy>(
std::move(__first), std::move(__middle), std::move(__last)).first;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -19,11 +19,9 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator, class _OutputIterator> template <class _ForwardIterator, class _OutputIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
_OutputIterator rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) {
rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) return std::copy(__first, __middle, std::copy(__middle, __last, __result));
{
return std::copy(__first, __middle, std::copy(__middle, __last, __result));
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -29,20 +29,23 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, template <class _AlgPolicy,
class _PopulationIterator, class _PopulationSentinel, class _SampleIterator, class _Distance, class _PopulationIterator,
class _PopulationSentinel,
class _SampleIterator,
class _Distance,
class _UniformRandomNumberGenerator> class _UniformRandomNumberGenerator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _SampleIterator __sample(
_SampleIterator __sample(_PopulationIterator __first, _PopulationIterator __first,
_PopulationSentinel __last, _SampleIterator __output_iter, _PopulationSentinel __last,
_Distance __n, _SampleIterator __output_iter,
_UniformRandomNumberGenerator& __g, _Distance __n,
input_iterator_tag) { _UniformRandomNumberGenerator& __g,
input_iterator_tag) {
_Distance __k = 0; _Distance __k = 0;
for (; __first != __last && __k < __n; ++__first, (void) ++__k) for (; __first != __last && __k < __n; ++__first, (void)++__k)
__output_iter[__k] = *__first; __output_iter[__k] = *__first;
_Distance __sz = __k; _Distance __sz = __k;
for (; __first != __last; ++__first, (void) ++__k) { for (; __first != __last; ++__first, (void)++__k) {
_Distance __r = uniform_int_distribution<_Distance>(0, __k)(__g); _Distance __r = uniform_int_distribution<_Distance>(0, __k)(__g);
if (__r < __sz) if (__r < __sz)
__output_iter[__r] = *__first; __output_iter[__r] = *__first;
@ -51,14 +54,18 @@ _SampleIterator __sample(_PopulationIterator __first,
} }
template <class _AlgPolicy, template <class _AlgPolicy,
class _PopulationIterator, class _PopulationSentinel, class _SampleIterator, class _Distance, class _PopulationIterator,
class _PopulationSentinel,
class _SampleIterator,
class _Distance,
class _UniformRandomNumberGenerator> class _UniformRandomNumberGenerator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _SampleIterator __sample(
_SampleIterator __sample(_PopulationIterator __first, _PopulationIterator __first,
_PopulationSentinel __last, _SampleIterator __output_iter, _PopulationSentinel __last,
_Distance __n, _SampleIterator __output_iter,
_UniformRandomNumberGenerator& __g, _Distance __n,
forward_iterator_tag) { _UniformRandomNumberGenerator& __g,
forward_iterator_tag) {
_Distance __unsampled_sz = _IterOps<_AlgPolicy>::distance(__first, __last); _Distance __unsampled_sz = _IterOps<_AlgPolicy>::distance(__first, __last);
for (__n = std::min(__n, __unsampled_sz); __n != 0; ++__first) { for (__n = std::min(__n, __unsampled_sz); __n != 0; ++__first) {
_Distance __r = uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); _Distance __r = uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g);
@ -71,36 +78,40 @@ _SampleIterator __sample(_PopulationIterator __first,
} }
template <class _AlgPolicy, template <class _AlgPolicy,
class _PopulationIterator, class _PopulationSentinel, class _SampleIterator, class _Distance, class _PopulationIterator,
class _PopulationSentinel,
class _SampleIterator,
class _Distance,
class _UniformRandomNumberGenerator> class _UniformRandomNumberGenerator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _SampleIterator __sample(
_SampleIterator __sample(_PopulationIterator __first, _PopulationIterator __first,
_PopulationSentinel __last, _SampleIterator __output_iter, _PopulationSentinel __last,
_Distance __n, _UniformRandomNumberGenerator& __g) { _SampleIterator __output_iter,
_Distance __n,
_UniformRandomNumberGenerator& __g) {
_LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0, "N must be a positive number."); _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0, "N must be a positive number.");
using _PopIterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_PopulationIterator>; using _PopIterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_PopulationIterator>;
using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>; using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>;
using _CommonType = typename common_type<_Distance, _Difference>::type; using _CommonType = typename common_type<_Distance, _Difference>::type;
return std::__sample<_AlgPolicy>( return std::__sample<_AlgPolicy>(
std::move(__first), std::move(__last), std::move(__output_iter), _CommonType(__n), std::move(__first), std::move(__last), std::move(__output_iter), _CommonType(__n), __g, _PopIterCategory());
__g, _PopIterCategory());
} }
#if _LIBCPP_STD_VER >= 17 #if _LIBCPP_STD_VER >= 17
template <class _PopulationIterator, class _SampleIterator, class _Distance, template <class _PopulationIterator, class _SampleIterator, class _Distance, class _UniformRandomNumberGenerator>
class _UniformRandomNumberGenerator> inline _LIBCPP_HIDE_FROM_ABI _SampleIterator
inline _LIBCPP_HIDE_FROM_ABI sample(_PopulationIterator __first,
_SampleIterator sample(_PopulationIterator __first, _PopulationIterator __last,
_PopulationIterator __last, _SampleIterator __output_iter, _SampleIterator __output_iter,
_Distance __n, _UniformRandomNumberGenerator&& __g) { _Distance __n,
_UniformRandomNumberGenerator&& __g) {
static_assert(__has_forward_iterator_category<_PopulationIterator>::value || static_assert(__has_forward_iterator_category<_PopulationIterator>::value ||
__has_random_access_iterator_category<_SampleIterator>::value, __has_random_access_iterator_category<_SampleIterator>::value,
"SampleIterator must meet the requirements of RandomAccessIterator"); "SampleIterator must meet the requirements of RandomAccessIterator");
return std::__sample<_ClassicAlgPolicy>( return std::__sample<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__output_iter), __n, __g);
std::move(__first), std::move(__last), std::move(__output_iter), __n, __g);
} }
#endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP_STD_VER >= 17

View File

@ -29,17 +29,15 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, template <class _AlgPolicy,
class _Iter1, class _Sent1, class _Iter1,
class _Iter2, class _Sent2, class _Sent1,
class _Iter2,
class _Sent2,
class _Pred, class _Pred,
class _Proj1, class _Proj1,
class _Proj2> class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_forward_impl(
pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
_Iter2 __first2, _Sent2 __last2,
_Pred& __pred,
_Proj1& __proj1,
_Proj2& __proj2) {
if (__first2 == __last2) if (__first2 == __last2)
return std::make_pair(__first1, __first1); // Everything matches an empty sequence return std::make_pair(__first1, __first1); // Everything matches an empty sequence
while (true) { while (true) {
@ -64,8 +62,7 @@ pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1,
} }
// if there is a mismatch, restart with a new __first1 // if there is a mismatch, restart with a new __first1
if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) {
{
++__first1; ++__first1;
break; break;
} // else there is a match, check next elements } // else there is a match, check next elements
@ -74,21 +71,25 @@ pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1,
} }
template <class _AlgPolicy, template <class _AlgPolicy,
class _Iter1, class _Sent1, class _Iter1,
class _Iter2, class _Sent2, class _Sent1,
class _Iter2,
class _Sent2,
class _Pred, class _Pred,
class _Proj1, class _Proj1,
class _Proj2, class _Proj2,
class _DiffT1, class _DiffT1,
class _DiffT2> class _DiffT2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_random_access_impl(
pair<_Iter1, _Iter1> __search_random_access_impl(_Iter1 __first1, _Sent1 __last1, _Iter1 __first1,
_Iter2 __first2, _Sent2 __last2, _Sent1 __last1,
_Pred& __pred, _Iter2 __first2,
_Proj1& __proj1, _Sent2 __last2,
_Proj2& __proj2, _Pred& __pred,
_DiffT1 __size1, _Proj1& __proj1,
_DiffT2 __size2) { _Proj2& __proj2,
_DiffT1 __size1,
_DiffT2 __size2) {
const _Iter1 __s = __first1 + __size1 - _DiffT1(__size2 - 1); // Start of pattern match can't go beyond here const _Iter1 __s = __first1 + __size1 - _DiffT1(__size2 - 1); // Start of pattern match can't go beyond here
while (true) { while (true) {
@ -116,20 +117,17 @@ pair<_Iter1, _Iter1> __search_random_access_impl(_Iter1 __first1, _Sent1 __last1
} }
} }
template <class _Iter1, class _Sent1, template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
class _Iter2, class _Sent2, _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_impl(
class _Pred, _Iter1 __first1,
class _Proj1, _Sent1 __last1,
class _Proj2> _Iter2 __first2,
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Sent2 __last2,
pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, _Pred& __pred,
_Iter2 __first2, _Sent2 __last2, _Proj1& __proj1,
_Pred& __pred, _Proj2& __proj2,
_Proj1& __proj1, __enable_if_t<__has_random_access_iterator_category<_Iter1>::value &&
_Proj2& __proj2, __has_random_access_iterator_category<_Iter2>::value>* = nullptr) {
__enable_if_t<__has_random_access_iterator_category<_Iter1>::value
&& __has_random_access_iterator_category<_Iter2>::value>* = nullptr) {
auto __size2 = __last2 - __first2; auto __size2 = __last2 - __first2;
if (__size2 == 0) if (__size2 == 0)
return std::make_pair(__first1, __first1); return std::make_pair(__first1, __first1);
@ -139,42 +137,32 @@ pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1,
return std::make_pair(__last1, __last1); return std::make_pair(__last1, __last1);
} }
return std::__search_random_access_impl<_ClassicAlgPolicy>(__first1, __last1, return std::__search_random_access_impl<_ClassicAlgPolicy>(
__first2, __last2, __first1, __last1, __first2, __last2, __pred, __proj1, __proj2, __size1, __size2);
__pred,
__proj1,
__proj2,
__size1,
__size2);
} }
template <class _Iter1, class _Sent1, template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
class _Iter2, class _Sent2, _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_impl(
class _Pred, _Iter1 __first1,
class _Proj1, _Sent1 __last1,
class _Proj2> _Iter2 __first2,
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Sent2 __last2,
pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, _Pred& __pred,
_Iter2 __first2, _Sent2 __last2, _Proj1& __proj1,
_Pred& __pred, _Proj2& __proj2,
_Proj1& __proj1, __enable_if_t<__has_forward_iterator_category<_Iter1>::value && __has_forward_iterator_category<_Iter2>::value &&
_Proj2& __proj2, !(__has_random_access_iterator_category<_Iter1>::value &&
__enable_if_t<__has_forward_iterator_category<_Iter1>::value __has_random_access_iterator_category<_Iter2>::value)>* = nullptr) {
&& __has_forward_iterator_category<_Iter2>::value return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2);
&& !(__has_random_access_iterator_category<_Iter1>::value
&& __has_random_access_iterator_category<_Iter2>::value)>* = nullptr) {
return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1,
__first2, __last2,
__pred,
__proj1,
__proj2);
} }
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1
_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, search(_ForwardIterator1 __first1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator1 __last1,
_BinaryPredicate __pred) { _ForwardIterator2 __first2,
_ForwardIterator2 __last2,
_BinaryPredicate __pred) {
static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value,
"BinaryPredicate has to be callable"); "BinaryPredicate has to be callable");
auto __proj = __identity(); auto __proj = __identity();
@ -182,9 +170,8 @@ _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
} }
template <class _ForwardIterator1, class _ForwardIterator2> template <class _ForwardIterator1, class _ForwardIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1
_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
_ForwardIterator2 __first2, _ForwardIterator2 __last2) {
return std::search(__first1, __last1, __first2, __last2, __equal_to()); return std::search(__first1, __last1, __first2, __last2, __equal_to());
} }

View File

@ -31,12 +31,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj> template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> __search_n_forward_impl(
pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last, _Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) {
_SizeT __count,
const _Type& __value,
_Pred& __pred,
_Proj& __proj) {
if (__count <= 0) if (__count <= 0)
return std::make_pair(__first, __first); return std::make_pair(__first, __first);
while (true) { while (true) {
@ -62,8 +58,7 @@ pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last,
} }
// if there is a mismatch, restart with a new __first // if there is a mismatch, restart with a new __first
if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) {
{
__first = __m; __first = __m;
++__first; ++__first;
break; break;
@ -73,13 +68,8 @@ pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last,
} }
template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj, class _DiffT> template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj, class _DiffT>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 std::pair<_Iter, _Iter> __search_n_random_access_impl(
std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __last, _Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj, _DiffT __size1) {
_SizeT __count,
const _Type& __value,
_Pred& __pred,
_Proj& __proj,
_DiffT __size1) {
using difference_type = typename iterator_traits<_Iter>::difference_type; using difference_type = typename iterator_traits<_Iter>::difference_type;
if (__count == 0) if (__count == 0)
return std::make_pair(__first, __first); return std::make_pair(__first, __first);
@ -109,8 +99,7 @@ std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __las
++__m; // no need to check range on __m because __s guarantees we have enough source ++__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 there is a mismatch, restart with a new __first
if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) {
{
__first = __m; __first = __m;
++__first; ++__first;
break; break;
@ -119,61 +108,44 @@ std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __las
} }
} }
template <class _Iter, class _Sent, template <class _Iter, class _Sent, class _DiffT, class _Type, class _Pred, class _Proj>
class _DiffT, _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> __search_n_impl(
class _Type, _Iter __first,
class _Pred, _Sent __last,
class _Proj> _DiffT __count,
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Type& __value,
pair<_Iter, _Iter> __search_n_impl(_Iter __first, _Sent __last, _Pred& __pred,
_DiffT __count, _Proj& __proj,
const _Type& __value, __enable_if_t<__has_random_access_iterator_category<_Iter>::value>* = nullptr) {
_Pred& __pred, return std::__search_n_random_access_impl<_ClassicAlgPolicy>(
_Proj& __proj, __first, __last, __count, __value, __pred, __proj, __last - __first);
__enable_if_t<__has_random_access_iterator_category<_Iter>::value>* = nullptr) {
return std::__search_n_random_access_impl<_ClassicAlgPolicy>(__first, __last,
__count,
__value,
__pred,
__proj,
__last - __first);
} }
template <class _Iter1, class _Sent1, template <class _Iter1, class _Sent1, class _DiffT, class _Type, class _Pred, class _Proj>
class _DiffT, _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_n_impl(
class _Type, _Iter1 __first,
class _Pred, _Sent1 __last,
class _Proj> _DiffT __count,
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Type& __value,
pair<_Iter1, _Iter1> __search_n_impl(_Iter1 __first, _Sent1 __last, _Pred& __pred,
_DiffT __count, _Proj& __proj,
const _Type& __value, __enable_if_t<__has_forward_iterator_category<_Iter1>::value &&
_Pred& __pred, !__has_random_access_iterator_category<_Iter1>::value>* = nullptr) {
_Proj& __proj, return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last, __count, __value, __pred, __proj);
__enable_if_t<__has_forward_iterator_category<_Iter1>::value
&& !__has_random_access_iterator_category<_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> template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search_n(
_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value, _BinaryPredicate __pred) {
_Size __count, static_assert(
const _Tp& __value, __is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value, "BinaryPredicate has to be callable");
_BinaryPredicate __pred) {
static_assert(__is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value,
"BinaryPredicate has to be callable");
auto __proj = __identity(); auto __proj = __identity();
return std::__search_n_impl(__first, __last, std::__convert_to_integral(__count), __value, __pred, __proj).first; return std::__search_n_impl(__first, __last, std::__convert_to_integral(__count), __value, __pred, __proj).first;
} }
template <class _ForwardIterator, class _Size, class _Tp> template <class _ForwardIterator, class _Size, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) { search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) {
return std::search_n(__first, __last, std::__convert_to_integral(__count), __value, __equal_to()); return std::search_n(__first, __last, std::__convert_to_integral(__count), __value, __equal_to());
} }

View File

@ -55,7 +55,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_d
_OutputIterator __result, _OutputIterator __result,
_Compare __comp) { _Compare __comp) {
return std::__set_difference<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( return std::__set_difference<_ClassicAlgPolicy, __comp_ref_type<_Compare> >(
__first1, __last1, __first2, __last2, __result, __comp) __first1, __last1, __first2, __last2, __result, __comp)
.second; .second;
} }

View File

@ -22,30 +22,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20 #if _LIBCPP_STD_VER >= 20
template <class _ForwardIterator> template <class _ForwardIterator>
inline _LIBCPP_HIDE_FROM_ABI constexpr inline _LIBCPP_HIDE_FROM_ABI constexpr _ForwardIterator
_ForwardIterator shift_left(_ForwardIterator __first,
shift_left(_ForwardIterator __first, _ForwardIterator __last, _ForwardIterator __last,
typename iterator_traits<_ForwardIterator>::difference_type __n) typename iterator_traits<_ForwardIterator>::difference_type __n) {
{ if (__n == 0) {
if (__n == 0) { return __last;
return __last; }
}
_ForwardIterator __m = __first; _ForwardIterator __m = __first;
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
if (__n >= __last - __first) { if (__n >= __last - __first) {
return __first; return __first;
}
__m += __n;
} else {
for (; __n > 0; --__n) {
if (__m == __last) {
return __first;
}
++__m;
}
} }
return std::move(__m, __last, __first); __m += __n;
} else {
for (; __n > 0; --__n) {
if (__m == __last) {
return __first;
}
++__m;
}
}
return std::move(__m, __last, __first);
} }
#endif // _LIBCPP_STD_VER >= 20 #endif // _LIBCPP_STD_VER >= 20

View File

@ -25,73 +25,72 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20 #if _LIBCPP_STD_VER >= 20
template <class _ForwardIterator> template <class _ForwardIterator>
inline _LIBCPP_HIDE_FROM_ABI constexpr inline _LIBCPP_HIDE_FROM_ABI constexpr _ForwardIterator
_ForwardIterator shift_right(_ForwardIterator __first,
shift_right(_ForwardIterator __first, _ForwardIterator __last, _ForwardIterator __last,
typename iterator_traits<_ForwardIterator>::difference_type __n) typename iterator_traits<_ForwardIterator>::difference_type __n) {
{ if (__n == 0) {
if (__n == 0) { return __first;
return __first; }
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
decltype(__n) __d = __last - __first;
if (__n >= __d) {
return __last;
}
_ForwardIterator __m = __first + (__d - __n);
return std::move_backward(__first, __m, __last);
} else if constexpr (__has_bidirectional_iterator_category<_ForwardIterator>::value) {
_ForwardIterator __m = __last;
for (; __n > 0; --__n) {
if (__m == __first) {
return __last;
}
--__m;
}
return std::move_backward(__first, __m, __last);
} else {
_ForwardIterator __ret = __first;
for (; __n > 0; --__n) {
if (__ret == __last) {
return __last;
}
++__ret;
} }
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { // We have an __n-element scratch space from __first to __ret.
decltype(__n) __d = __last - __first; // Slide an __n-element window [__trail, __lead) from left to right.
if (__n >= __d) { // We're essentially doing swap_ranges(__first, __ret, __trail, __lead)
return __last; // over and over; but once __lead reaches __last we needn't bother
} // to save the values of elements [__trail, __last).
_ForwardIterator __m = __first + (__d - __n);
return std::move_backward(__first, __m, __last);
} else if constexpr (__has_bidirectional_iterator_category<_ForwardIterator>::value) {
_ForwardIterator __m = __last;
for (; __n > 0; --__n) {
if (__m == __first) {
return __last;
}
--__m;
}
return std::move_backward(__first, __m, __last);
} else {
_ForwardIterator __ret = __first;
for (; __n > 0; --__n) {
if (__ret == __last) {
return __last;
}
++__ret;
}
// We have an __n-element scratch space from __first to __ret. auto __trail = __first;
// Slide an __n-element window [__trail, __lead) from left to right. auto __lead = __ret;
// We're essentially doing swap_ranges(__first, __ret, __trail, __lead) while (__trail != __ret) {
// over and over; but once __lead reaches __last we needn't bother if (__lead == __last) {
// to save the values of elements [__trail, __last). std::move(__first, __trail, __ret);
return __ret;
auto __trail = __first; }
auto __lead = __ret; ++__trail;
while (__trail != __ret) { ++__lead;
if (__lead == __last) {
std::move(__first, __trail, __ret);
return __ret;
}
++__trail;
++__lead;
}
_ForwardIterator __mid = __first;
while (true) {
if (__lead == __last) {
__trail = std::move(__mid, __ret, __trail);
std::move(__first, __mid, __trail);
return __ret;
}
swap(*__mid, *__trail);
++__mid;
++__trail;
++__lead;
if (__mid == __ret) {
__mid = __first;
}
}
} }
_ForwardIterator __mid = __first;
while (true) {
if (__lead == __last) {
__trail = std::move(__mid, __ret, __trail);
std::move(__first, __mid, __trail);
return __ret;
}
swap(*__mid, *__trail);
++__mid;
++__trail;
++__lead;
if (__mid == __ret) {
__mid = __first;
}
}
}
} }
#endif // _LIBCPP_STD_VER >= 20 #endif // _LIBCPP_STD_VER >= 20

View File

@ -32,8 +32,8 @@ class _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_randomizer {
public: public:
_LIBCPP_HIDE_FROM_ABI __libcpp_debug_randomizer() { _LIBCPP_HIDE_FROM_ABI __libcpp_debug_randomizer() {
__state_ = __seed(); __state_ = __seed();
__inc_ = __state_ + 0xda3e39cb94b95bdbULL; __inc_ = __state_ + 0xda3e39cb94b95bdbULL;
__inc_ = (__inc_ << 1) | 1; __inc_ = (__inc_ << 1) | 1;
} }
typedef uint_fast32_t result_type; typedef uint_fast32_t result_type;
@ -42,7 +42,7 @@ public:
_LIBCPP_HIDE_FROM_ABI result_type operator()() { _LIBCPP_HIDE_FROM_ABI result_type operator()() {
uint_fast64_t __oldstate = __state_; uint_fast64_t __oldstate = __state_;
__state_ = __oldstate * 6364136223846793005ULL + __inc_; __state_ = __oldstate * 6364136223846793005ULL + __inc_;
return __oldstate >> 32; return __oldstate >> 32;
} }
@ -62,102 +62,95 @@ private:
} }
}; };
#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \ #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) || defined(_LIBCPP_BUILDING_LIBRARY)
|| defined(_LIBCPP_BUILDING_LIBRARY)
class _LIBCPP_EXPORTED_FROM_ABI __rs_default; class _LIBCPP_EXPORTED_FROM_ABI __rs_default;
_LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get(); _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get();
class _LIBCPP_EXPORTED_FROM_ABI __rs_default class _LIBCPP_EXPORTED_FROM_ABI __rs_default {
{ static unsigned __c_;
static unsigned __c_;
__rs_default();
__rs_default();
public: public:
typedef uint_fast32_t result_type; typedef uint_fast32_t result_type;
static const result_type _Min = 0; static const result_type _Min = 0;
static const result_type _Max = 0xFFFFFFFF; static const result_type _Max = 0xFFFFFFFF;
__rs_default(const __rs_default&); __rs_default(const __rs_default&);
~__rs_default(); ~__rs_default();
result_type operator()(); result_type operator()();
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() {return _Min;} static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() { return _Min; }
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() {return _Max;} static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() { return _Max; }
friend _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get(); friend _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get();
}; };
_LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get(); _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get();
template <class _RandomAccessIterator> template <class _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) {
{ typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef uniform_int_distribution<ptrdiff_t> _Dp;
typedef uniform_int_distribution<ptrdiff_t> _Dp; typedef typename _Dp::param_type _Pp;
typedef typename _Dp::param_type _Pp; difference_type __d = __last - __first;
difference_type __d = __last - __first; if (__d > 1) {
if (__d > 1) _Dp __uid;
{ __rs_default __g = __rs_get();
_Dp __uid; for (--__last, (void)--__d; __first < __last; ++__first, (void)--__d) {
__rs_default __g = __rs_get(); difference_type __i = __uid(__g, _Pp(0, __d));
for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) if (__i != difference_type(0))
{ swap(*__first, *(__first + __i));
difference_type __i = __uid(__g, _Pp(0, __d));
if (__i != difference_type(0))
swap(*__first, *(__first + __i));
}
} }
}
} }
template <class _RandomAccessIterator, class _RandomNumberGenerator> template <class _RandomAccessIterator, class _RandomNumberGenerator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, random_shuffle(_RandomAccessIterator __first,
#ifndef _LIBCPP_CXX03_LANG _RandomAccessIterator __last,
# ifndef _LIBCPP_CXX03_LANG
_RandomNumberGenerator&& __rand) _RandomNumberGenerator&& __rand)
#else # else
_RandomNumberGenerator& __rand) _RandomNumberGenerator& __rand)
#endif # endif
{ {
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
difference_type __d = __last - __first; difference_type __d = __last - __first;
if (__d > 1) if (__d > 1) {
{ for (--__last; __first < __last; ++__first, (void)--__d) {
for (--__last; __first < __last; ++__first, (void) --__d) difference_type __i = __rand(__d);
{ if (__i != difference_type(0))
difference_type __i = __rand(__d); swap(*__first, *(__first + __i));
if (__i != difference_type(0))
swap(*__first, *(__first + __i));
}
} }
}
} }
#endif #endif
template <class _AlgPolicy, class _RandomAccessIterator, class _Sentinel, class _UniformRandomNumberGenerator> template <class _AlgPolicy, class _RandomAccessIterator, class _Sentinel, class _UniformRandomNumberGenerator>
_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator __shuffle( _LIBCPP_HIDE_FROM_ABI _RandomAccessIterator
_RandomAccessIterator __first, _Sentinel __last_sentinel, _UniformRandomNumberGenerator&& __g) { __shuffle(_RandomAccessIterator __first, _Sentinel __last_sentinel, _UniformRandomNumberGenerator&& __g) {
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef uniform_int_distribution<ptrdiff_t> _Dp; typedef uniform_int_distribution<ptrdiff_t> _Dp;
typedef typename _Dp::param_type _Pp; typedef typename _Dp::param_type _Pp;
auto __original_last = _IterOps<_AlgPolicy>::next(__first, __last_sentinel); auto __original_last = _IterOps<_AlgPolicy>::next(__first, __last_sentinel);
auto __last = __original_last; auto __last = __original_last;
difference_type __d = __last - __first; difference_type __d = __last - __first;
if (__d > 1) if (__d > 1) {
{ _Dp __uid;
_Dp __uid; for (--__last, (void)--__d; __first < __last; ++__first, (void)--__d) {
for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) difference_type __i = __uid(__g, _Pp(0, __d));
{ if (__i != difference_type(0))
difference_type __i = __uid(__g, _Pp(0, __d)); _IterOps<_AlgPolicy>::iter_swap(__first, __first + __i);
if (__i != difference_type(0))
_IterOps<_AlgPolicy>::iter_swap(__first, __first + __i);
}
} }
}
return __original_last; return __original_last;
} }
template <class _RandomAccessIterator, class _UniformRandomNumberGenerator> template <class _RandomAccessIterator, class _UniformRandomNumberGenerator>

View File

@ -26,90 +26,89 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
__sift_down(_RandomAccessIterator __first, _Compare&& __comp, __sift_down(_RandomAccessIterator __first,
_Compare&& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len, typename iterator_traits<_RandomAccessIterator>::difference_type __len,
_RandomAccessIterator __start) _RandomAccessIterator __start) {
{ using _Ops = _IterOps<_AlgPolicy>;
using _Ops = _IterOps<_AlgPolicy>;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
// left-child of __start is at 2 * __start + 1 // left-child of __start is at 2 * __start + 1
// right-child of __start is at 2 * __start + 2 // right-child of __start is at 2 * __start + 2
difference_type __child = __start - __first; difference_type __child = __start - __first;
if (__len < 2 || (__len - 2) / 2 < __child) if (__len < 2 || (__len - 2) / 2 < __child)
return; return;
__child = 2 * __child + 1; __child = 2 * __child + 1;
_RandomAccessIterator __child_i = __first + __child; _RandomAccessIterator __child_i = __first + __child;
if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
// right-child exists and is greater than left-child
++__child_i;
++__child;
}
// check if we are in heap-order
if (__comp(*__child_i, *__start))
// we are, __start is larger than its largest child
return;
value_type __top(_Ops::__iter_move(__start));
do {
// we are not in heap-order, swap the parent with its largest child
*__start = _Ops::__iter_move(__child_i);
__start = __child_i;
if ((__len - 2) / 2 < __child)
break;
// recompute the child based off of the updated parent
__child = 2 * __child + 1;
__child_i = __first + __child;
if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
// right-child exists and is greater than left-child // right-child exists and is greater than left-child
++__child_i; ++__child_i;
++__child; ++__child;
} }
// check if we are in heap-order // check if we are in heap-order
if (__comp(*__child_i, *__start)) } while (!__comp(*__child_i, __top));
// we are, __start is larger than its largest child *__start = std::move(__top);
return;
value_type __top(_Ops::__iter_move(__start));
do
{
// we are not in heap-order, swap the parent with its largest child
*__start = _Ops::__iter_move(__child_i);
__start = __child_i;
if ((__len - 2) / 2 < __child)
break;
// recompute the child based off of the updated parent
__child = 2 * __child + 1;
__child_i = __first + __child;
if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
// right-child exists and is greater than left-child
++__child_i;
++__child;
}
// check if we are in heap-order
} while (!__comp(*__child_i, __top));
*__start = std::move(__top);
} }
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator __floyd_sift_down(
__floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp, _RandomAccessIterator __first,
typename iterator_traits<_RandomAccessIterator>::difference_type __len) _Compare&& __comp,
{ typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
_LIBCPP_ASSERT_UNCATEGORIZED(__len >= 2, "shouldn't be called unless __len >= 2"); _LIBCPP_ASSERT_UNCATEGORIZED(__len >= 2, "shouldn't be called unless __len >= 2");
_RandomAccessIterator __hole = __first; _RandomAccessIterator __hole = __first;
_RandomAccessIterator __child_i = __first; _RandomAccessIterator __child_i = __first;
difference_type __child = 0; difference_type __child = 0;
while (true) { while (true) {
__child_i += difference_type(__child + 1); __child_i += difference_type(__child + 1);
__child = 2 * __child + 1; __child = 2 * __child + 1;
if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
// right-child exists and is greater than left-child // right-child exists and is greater than left-child
++__child_i; ++__child_i;
++__child; ++__child;
}
// swap __hole with its largest child
*__hole = _IterOps<_AlgPolicy>::__iter_move(__child_i);
__hole = __child_i;
// if __hole is now a leaf, we're done
if (__child > (__len - 2) / 2)
return __hole;
} }
// swap __hole with its largest child
*__hole = _IterOps<_AlgPolicy>::__iter_move(__child_i);
__hole = __child_i;
// if __hole is now a leaf, we're done
if (__child > (__len - 2) / 2)
return __hole;
}
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -44,49 +44,47 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// stable, 2-3 compares, 0-2 swaps // stable, 2-3 compares, 0-2 swaps
template <class _AlgPolicy, class _Compare, class _ForwardIterator> template <class _AlgPolicy, class _Compare, class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 unsigned
_LIBCPP_CONSTEXPR_SINCE_CXX14 unsigned __sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, __sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c) {
_Compare __c) {
using _Ops = _IterOps<_AlgPolicy>; using _Ops = _IterOps<_AlgPolicy>;
unsigned __r = 0; unsigned __r = 0;
if (!__c(*__y, *__x)) // if x <= y if (!__c(*__y, *__x)) // if x <= y
{ {
if (!__c(*__z, *__y)) // if y <= z if (!__c(*__z, *__y)) // if y <= z
return __r; // x <= y && y <= z return __r; // x <= y && y <= z
// x <= y && y > z // x <= y && y > z
_Ops::iter_swap(__y, __z); // x <= z && y < z _Ops::iter_swap(__y, __z); // x <= z && y < z
__r = 1; __r = 1;
if (__c(*__y, *__x)) // if x > y if (__c(*__y, *__x)) // if x > y
{ {
_Ops::iter_swap(__x, __y); // x < y && y <= z _Ops::iter_swap(__x, __y); // x < y && y <= z
__r = 2; __r = 2;
} }
return __r; // x <= y && y < z return __r; // x <= y && y < z
} }
if (__c(*__z, *__y)) // x > y, if y > z if (__c(*__z, *__y)) // x > y, if y > z
{ {
_Ops::iter_swap(__x, __z); // x < y && y < z _Ops::iter_swap(__x, __z); // x < y && y < z
__r = 1; __r = 1;
return __r; return __r;
} }
_Ops::iter_swap(__x, __y); // x > y && y <= z _Ops::iter_swap(__x, __y); // x > y && y <= z
__r = 1; // x < y && x <= z __r = 1; // x < y && x <= z
if (__c(*__z, *__y)) // if y > z if (__c(*__z, *__y)) // if y > z
{ {
_Ops::iter_swap(__y, __z); // x <= y && y < z _Ops::iter_swap(__y, __z); // x <= y && y < z
__r = 2; __r = 2;
} }
return __r; return __r;
} // x <= y && y <= z } // x <= y && y <= z
// stable, 3-6 compares, 0-5 swaps // stable, 3-6 compares, 0-5 swaps
template <class _AlgPolicy, class _Compare, class _ForwardIterator> template <class _AlgPolicy, class _Compare, class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI void
void __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, _Compare __c) {
_Compare __c) { using _Ops = _IterOps<_AlgPolicy>;
using _Ops = _IterOps<_AlgPolicy>;
std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c);
if (__c(*__x4, *__x3)) { if (__c(*__x4, *__x3)) {
_Ops::iter_swap(__x3, __x4); _Ops::iter_swap(__x3, __x4);
@ -102,8 +100,13 @@ void __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3
// stable, 4-10 compares, 0-9 swaps // stable, 4-10 compares, 0-9 swaps
template <class _AlgPolicy, class _Comp, class _ForwardIterator> template <class _AlgPolicy, class _Comp, class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI void __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _LIBCPP_HIDE_FROM_ABI void
_ForwardIterator __x4, _ForwardIterator __x5, _Comp __comp) { __sort5(_ForwardIterator __x1,
_ForwardIterator __x2,
_ForwardIterator __x3,
_ForwardIterator __x4,
_ForwardIterator __x5,
_Comp __comp) {
using _Ops = _IterOps<_AlgPolicy>; using _Ops = _IterOps<_AlgPolicy>;
std::__sort4<_AlgPolicy, _Comp>(__x1, __x2, __x3, __x4, __comp); std::__sort4<_AlgPolicy, _Comp>(__x1, __x2, __x3, __x4, __comp);
@ -139,8 +142,9 @@ struct __is_simple_comparator<ranges::greater&> : true_type {};
template <class _Compare, class _Iter, class _Tp = typename iterator_traits<_Iter>::value_type> template <class _Compare, class _Iter, class _Tp = typename iterator_traits<_Iter>::value_type>
using __use_branchless_sort = using __use_branchless_sort =
integral_constant<bool, __libcpp_is_contiguous_iterator<_Iter>::value && sizeof(_Tp) <= sizeof(void*) && integral_constant<bool,
is_arithmetic<_Tp>::value && __is_simple_comparator<_Compare>::value>; __libcpp_is_contiguous_iterator<_Iter>::value && sizeof(_Tp) <= sizeof(void*) &&
is_arithmetic<_Tp>::value && __is_simple_comparator<_Compare>::value>;
namespace __detail { namespace __detail {
@ -154,49 +158,56 @@ template <class _Compare, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI void __cond_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _Compare __c) { inline _LIBCPP_HIDE_FROM_ABI void __cond_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _Compare __c) {
// Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`). // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`).
using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
bool __r = __c(*__x, *__y); bool __r = __c(*__x, *__y);
value_type __tmp = __r ? *__x : *__y; value_type __tmp = __r ? *__x : *__y;
*__y = __r ? *__y : *__x; *__y = __r ? *__y : *__x;
*__x = __tmp; *__x = __tmp;
} }
// Ensures that *__x, *__y and *__z are ordered according to the comparator __c, // Ensures that *__x, *__y and *__z are ordered according to the comparator __c,
// under the assumption that *__y and *__z are already ordered. // under the assumption that *__y and *__z are already ordered.
template <class _Compare, class _RandomAccessIterator> template <class _Compare, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI void __partially_sorted_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, inline _LIBCPP_HIDE_FROM_ABI void
_RandomAccessIterator __z, _Compare __c) { __partially_sorted_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _RandomAccessIterator __z, _Compare __c) {
// Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`). // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`).
using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
bool __r = __c(*__z, *__x); bool __r = __c(*__z, *__x);
value_type __tmp = __r ? *__z : *__x; value_type __tmp = __r ? *__z : *__x;
*__z = __r ? *__x : *__z; *__z = __r ? *__x : *__z;
__r = __c(__tmp, *__y); __r = __c(__tmp, *__y);
*__x = __r ? *__x : *__y; *__x = __r ? *__x : *__y;
*__y = __r ? *__y : __tmp; *__y = __r ? *__y : __tmp;
} }
template <class, class _Compare, class _RandomAccessIterator, template <class,
class _Compare,
class _RandomAccessIterator,
__enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, int> = 0> __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI void inline _LIBCPP_HIDE_FROM_ABI void __sort3_maybe_branchless(
__sort3_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, _RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, _Compare __c) {
_Compare __c) {
std::__cond_swap<_Compare>(__x2, __x3, __c); std::__cond_swap<_Compare>(__x2, __x3, __c);
std::__partially_sorted_swap<_Compare>(__x1, __x2, __x3, __c); std::__partially_sorted_swap<_Compare>(__x1, __x2, __x3, __c);
} }
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, template <class _AlgPolicy,
class _Compare,
class _RandomAccessIterator,
__enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>::value, int> = 0> __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI void inline _LIBCPP_HIDE_FROM_ABI void __sort3_maybe_branchless(
__sort3_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, _RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, _Compare __c) {
_Compare __c) {
std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c);
} }
template <class, class _Compare, class _RandomAccessIterator, template <class,
class _Compare,
class _RandomAccessIterator,
__enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, int> = 0> __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI void inline _LIBCPP_HIDE_FROM_ABI void __sort4_maybe_branchless(
__sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, _RandomAccessIterator __x1,
_RandomAccessIterator __x4, _Compare __c) { _RandomAccessIterator __x2,
_RandomAccessIterator __x3,
_RandomAccessIterator __x4,
_Compare __c) {
std::__cond_swap<_Compare>(__x1, __x3, __c); std::__cond_swap<_Compare>(__x1, __x3, __c);
std::__cond_swap<_Compare>(__x2, __x4, __c); std::__cond_swap<_Compare>(__x2, __x4, __c);
std::__cond_swap<_Compare>(__x1, __x2, __c); std::__cond_swap<_Compare>(__x1, __x2, __c);
@ -204,18 +215,24 @@ __sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2,
std::__cond_swap<_Compare>(__x2, __x3, __c); std::__cond_swap<_Compare>(__x2, __x3, __c);
} }
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, template <class _AlgPolicy,
class _Compare,
class _RandomAccessIterator,
__enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>::value, int> = 0> __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI void inline _LIBCPP_HIDE_FROM_ABI void __sort4_maybe_branchless(
__sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, _RandomAccessIterator __x1,
_RandomAccessIterator __x4, _Compare __c) { _RandomAccessIterator __x2,
_RandomAccessIterator __x3,
_RandomAccessIterator __x4,
_Compare __c) {
std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c); std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c);
} }
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, template <class _AlgPolicy,
class _Compare,
class _RandomAccessIterator,
__enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, int> = 0> __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI void inline _LIBCPP_HIDE_FROM_ABI void __sort5_maybe_branchless(
__sort5_maybe_branchless(
_RandomAccessIterator __x1, _RandomAccessIterator __x1,
_RandomAccessIterator __x2, _RandomAccessIterator __x2,
_RandomAccessIterator __x3, _RandomAccessIterator __x3,
@ -230,20 +247,25 @@ __sort5_maybe_branchless(
std::__partially_sorted_swap<_Compare>(__x2, __x3, __x4, __c); std::__partially_sorted_swap<_Compare>(__x2, __x3, __x4, __c);
} }
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, template <class _AlgPolicy,
class _Compare,
class _RandomAccessIterator,
__enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>::value, int> = 0> __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI void inline _LIBCPP_HIDE_FROM_ABI void __sort5_maybe_branchless(
__sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, _RandomAccessIterator __x1,
_RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) { _RandomAccessIterator __x2,
_RandomAccessIterator __x3,
_RandomAccessIterator __x4,
_RandomAccessIterator __x5,
_Compare __c) {
std::__sort5<_AlgPolicy, _Compare, _RandomAccessIterator>( std::__sort5<_AlgPolicy, _Compare, _RandomAccessIterator>(
std::move(__x1), std::move(__x2), std::move(__x3), std::move(__x4), std::move(__x5), __c); std::move(__x1), std::move(__x2), std::move(__x3), std::move(__x4), std::move(__x5), __c);
} }
// Assumes size > 0 // Assumes size > 0
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator> template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
_LIBCPP_CONSTEXPR_SINCE_CXX14 void __selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, __selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
_Compare __comp) {
_BidirectionalIterator __lm1 = __last; _BidirectionalIterator __lm1 = __last;
for (--__lm1; __first != __lm1; ++__first) { for (--__lm1; __first != __lm1; ++__first) {
_BidirectionalIterator __i = std::__min_element<_Compare>(__first, __last, __comp); _BidirectionalIterator __i = std::__min_element<_Compare>(__first, __last, __comp);
@ -255,8 +277,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 void __selection_sort(_BidirectionalIterator __fir
// Sort the iterator range [__first, __last) using the comparator __comp using // Sort the iterator range [__first, __last) using the comparator __comp using
// the insertion sort algorithm. // the insertion sort algorithm.
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator> template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI void
void __insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { __insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
using _Ops = _IterOps<_AlgPolicy>; using _Ops = _IterOps<_AlgPolicy>;
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
@ -292,16 +314,17 @@ __insertion_sort_unguarded(_RandomAccessIterator const __first, _RandomAccessIte
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
if (__first == __last) if (__first == __last)
return; return;
const _RandomAccessIterator __leftmost = __first - difference_type(1); (void)__leftmost; // can be unused when assertions are disabled const _RandomAccessIterator __leftmost = __first - difference_type(1);
(void)__leftmost; // can be unused when assertions are disabled
for (_RandomAccessIterator __i = __first + difference_type(1); __i != __last; ++__i) { for (_RandomAccessIterator __i = __first + difference_type(1); __i != __last; ++__i) {
_RandomAccessIterator __j = __i - difference_type(1); _RandomAccessIterator __j = __i - difference_type(1);
if (__comp(*__i, *__j)) { if (__comp(*__i, *__j)) {
value_type __t(_Ops::__iter_move(__i)); value_type __t(_Ops::__iter_move(__i));
_RandomAccessIterator __k = __j; _RandomAccessIterator __k = __j;
__j = __i; __j = __i;
do { do {
*__j = _Ops::__iter_move(__k); *__j = _Ops::__iter_move(__k);
__j = __k; __j = __k;
_LIBCPP_ASSERT_UNCATEGORIZED( _LIBCPP_ASSERT_UNCATEGORIZED(
__k != __leftmost, __k != __leftmost,
"Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
@ -312,8 +335,8 @@ __insertion_sort_unguarded(_RandomAccessIterator const __first, _RandomAccessIte
} }
template <class _AlgPolicy, class _Comp, class _RandomAccessIterator> template <class _AlgPolicy, class _Comp, class _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI bool __insertion_sort_incomplete( _LIBCPP_HIDE_FROM_ABI bool
_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { __insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
using _Ops = _IterOps<_AlgPolicy>; using _Ops = _IterOps<_AlgPolicy>;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
@ -334,23 +357,27 @@ _LIBCPP_HIDE_FROM_ABI bool __insertion_sort_incomplete(
return true; return true;
case 5: case 5:
std::__sort5_maybe_branchless<_AlgPolicy, _Comp>( std::__sort5_maybe_branchless<_AlgPolicy, _Comp>(
__first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3), __first,
--__last, __comp); __first + difference_type(1),
__first + difference_type(2),
__first + difference_type(3),
--__last,
__comp);
return true; return true;
} }
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
_RandomAccessIterator __j = __first + difference_type(2); _RandomAccessIterator __j = __first + difference_type(2);
std::__sort3_maybe_branchless<_AlgPolicy, _Comp>(__first, __first + difference_type(1), __j, __comp); std::__sort3_maybe_branchless<_AlgPolicy, _Comp>(__first, __first + difference_type(1), __j, __comp);
const unsigned __limit = 8; const unsigned __limit = 8;
unsigned __count = 0; unsigned __count = 0;
for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) { for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) {
if (__comp(*__i, *__j)) { if (__comp(*__i, *__j)) {
value_type __t(_Ops::__iter_move(__i)); value_type __t(_Ops::__iter_move(__i));
_RandomAccessIterator __k = __j; _RandomAccessIterator __k = __j;
__j = __i; __j = __i;
do { do {
*__j = _Ops::__iter_move(__k); *__j = _Ops::__iter_move(__k);
__j = __k; __j = __k;
} while (__j != __first && __comp(__t, *--__k)); } while (__j != __first && __comp(__t, *--__k));
*__j = std::move(__t); *__j = std::move(__t);
if (++__count == __limit) if (++__count == __limit)
@ -507,8 +534,9 @@ __bitset_partition(_RandomAccessIterator __first, _RandomAccessIterator __last,
typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
_LIBCPP_ASSERT_UNCATEGORIZED(__last - __first >= difference_type(3), ""); _LIBCPP_ASSERT_UNCATEGORIZED(__last - __first >= difference_type(3), "");
const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around
const _RandomAccessIterator __end = __last; (void)__end; // const _RandomAccessIterator __end = __last;
(void)__end; //
value_type __pivot(_Ops::__iter_move(__first)); value_type __pivot(_Ops::__iter_move(__first));
// Find the first element greater than the pivot. // Find the first element greater than the pivot.
@ -598,8 +626,9 @@ __partition_with_equals_on_right(_RandomAccessIterator __first, _RandomAccessIte
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
_LIBCPP_ASSERT_UNCATEGORIZED(__last - __first >= difference_type(3), ""); _LIBCPP_ASSERT_UNCATEGORIZED(__last - __first >= difference_type(3), "");
const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around
const _RandomAccessIterator __end = __last; (void)__end; // const _RandomAccessIterator __end = __last;
(void)__end; //
value_type __pivot(_Ops::__iter_move(__first)); value_type __pivot(_Ops::__iter_move(__first));
// Find the first element greater or equal to the pivot. It will be always // Find the first element greater or equal to the pivot. It will be always
// guarded because __introsort will do the median-of-three before calling // guarded because __introsort will do the median-of-three before calling
@ -665,8 +694,9 @@ __partition_with_equals_on_left(_RandomAccessIterator __first, _RandomAccessIter
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
// TODO(LLVM18): Make __begin const, see https://reviews.llvm.org/D147089#4349748 // TODO(LLVM18): Make __begin const, see https://reviews.llvm.org/D147089#4349748
_RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around
const _RandomAccessIterator __end = __last; (void)__end; // const _RandomAccessIterator __end = __last;
(void)__end; //
value_type __pivot(_Ops::__iter_move(__first)); value_type __pivot(_Ops::__iter_move(__first));
if (__comp(__pivot, *(__last - difference_type(1)))) { if (__comp(__pivot, *(__last - difference_type(1)))) {
// Guarded. // Guarded.
@ -753,8 +783,12 @@ void __introsort(_RandomAccessIterator __first,
return; return;
case 5: case 5:
std::__sort5_maybe_branchless<_AlgPolicy, _Compare>( std::__sort5_maybe_branchless<_AlgPolicy, _Compare>(
__first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3), __first,
--__last, __comp); __first + difference_type(1),
__first + difference_type(2),
__first + difference_type(3),
--__last,
__comp);
return; return;
} }
// Use insertion sort if the length of the range is below the specified limit. // Use insertion sort if the length of the range is below the specified limit.
@ -803,10 +837,10 @@ void __introsort(_RandomAccessIterator __first,
continue; continue;
} }
// Use bitset partition only if asked for. // Use bitset partition only if asked for.
auto __ret = auto __ret = _UseBitSetPartition
_UseBitSetPartition ? std::__bitset_partition<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp)
? std::__bitset_partition<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp) : std::__partition_with_equals_on_right<_AlgPolicy, _RandomAccessIterator, _Compare>(
: std::__partition_with_equals_on_right<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp); __first, __last, __comp);
_RandomAccessIterator __i = __ret.first; _RandomAccessIterator __i = __ret.first;
// [__first, __i) < *__i and *__i <= [__i+1, __last) // [__first, __i) < *__i and *__i <= [__i+1, __last)
// If we were given a perfect partition, see if insertion sort is quick... // If we were given a perfect partition, see if insertion sort is quick...
@ -858,19 +892,27 @@ extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<char>&, char*>(char
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&); extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
#endif #endif
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&); extern template _LIBCPP_EXPORTED_FROM_ABI void
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&); __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
extern template _LIBCPP_EXPORTED_FROM_ABI void
__sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<short>&, short*>(short*, short*, __less<short>&); extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<short>&, short*>(short*, short*, __less<short>&);
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&); extern template _LIBCPP_EXPORTED_FROM_ABI void
__sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<int>&, int*>(int*, int*, __less<int>&); extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<int>&, int*>(int*, int*, __less<int>&);
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&); extern template _LIBCPP_EXPORTED_FROM_ABI void
__sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long>&, long*>(long*, long*, __less<long>&); extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long>&, long*>(long*, long*, __less<long>&);
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&); extern template _LIBCPP_EXPORTED_FROM_ABI void
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&); __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&); extern template _LIBCPP_EXPORTED_FROM_ABI void
__sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned long long>&, unsigned long long*>(
unsigned long long*, unsigned long long*, __less<unsigned long long>&);
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<float>&, float*>(float*, float*, __less<float>&); extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<float>&, float*>(float*, float*, __less<float>&);
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<double>&, double*>(double*, double*, __less<double>&); extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<double>&, double*>(double*, double*, __less<double>&);
extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&); extern template _LIBCPP_EXPORTED_FROM_ABI void
__sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
template <class _AlgPolicy, class _RandomAccessIterator, class _Comp> template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
@ -884,8 +926,7 @@ __sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co
std::__introsort<_AlgPolicy, std::__introsort<_AlgPolicy,
_Comp&, _Comp&,
_RandomAccessIterator, _RandomAccessIterator,
__use_branchless_sort<_Comp, _RandomAccessIterator>::value>( __use_branchless_sort<_Comp, _RandomAccessIterator>::value>(__first, __last, __comp, __depth_limit);
__first, __last, __comp, __depth_limit);
} }
template <class _Type, class... _Options> template <class _Type, class... _Options>
@ -941,8 +982,8 @@ _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, ranges
#endif #endif
template <class _AlgPolicy, class _RandomAccessIterator, class _Comp> template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
std::__debug_randomize_range<_AlgPolicy>(__first, __last); std::__debug_randomize_range<_AlgPolicy>(__first, __last);
if (__libcpp_is_constant_evaluated()) { if (__libcpp_is_constant_evaluated()) {
@ -955,14 +996,14 @@ void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _C
} }
template <class _RandomAccessIterator, class _Comp> template <class _RandomAccessIterator, class _Comp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
std::__sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); std::__sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp);
} }
template <class _RandomAccessIterator> template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::sort(__first, __last, __less<>()); std::sort(__first, __last, __less<>());
} }

View File

@ -27,20 +27,20 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) {
_RandomAccessIterator __saved_last = __last; _RandomAccessIterator __saved_last = __last;
__comp_ref_type<_Compare> __comp_ref = __comp; __comp_ref_type<_Compare> __comp_ref = __comp;
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n) for (difference_type __n = __last - __first; __n > 1; --__last, (void)--__n)
std::__pop_heap<_AlgPolicy>(__first, __last, __comp_ref, __n); std::__pop_heap<_AlgPolicy>(__first, __last, __comp_ref, __n);
std::__check_strict_weak_ordering_sorted(__first, __saved_last, __comp_ref); std::__check_strict_weak_ordering_sorted(__first, __saved_last, __comp_ref);
} }
template <class _RandomAccessIterator, class _Compare> template <class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible.");
static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable.");
@ -48,8 +48,8 @@ void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
} }
template <class _RandomAccessIterator> template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::sort_heap(std::move(__first), std::move(__last), __less<>()); std::sort_heap(std::move(__first), std::move(__last), __less<>());
} }

View File

@ -29,296 +29,269 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Predicate, class _ForwardIterator, class _Distance, class _Pair> template <class _AlgPolicy, class _Predicate, class _ForwardIterator, class _Distance, class _Pair>
_LIBCPP_HIDE_FROM_ABI _ForwardIterator _LIBCPP_HIDE_FROM_ABI _ForwardIterator __stable_partition_impl(
__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, _ForwardIterator __first,
_Distance __len, _Pair __p, forward_iterator_tag __fit) _ForwardIterator __last,
{ _Predicate __pred,
using _Ops = _IterOps<_AlgPolicy>; _Distance __len,
_Pair __p,
forward_iterator_tag __fit) {
using _Ops = _IterOps<_AlgPolicy>;
// *__first is known to be false // *__first is known to be false
// __len >= 1 // __len >= 1
if (__len == 1) if (__len == 1)
return __first; return __first;
if (__len == 2) if (__len == 2) {
{ _ForwardIterator __m = __first;
_ForwardIterator __m = __first; if (__pred(*++__m)) {
if (__pred(*++__m)) _Ops::iter_swap(__first, __m);
{ return __m;
_Ops::iter_swap(__first, __m);
return __m;
}
return __first;
} }
if (__len <= __p.second) return __first;
{ // The buffer is big enough to use }
typedef typename iterator_traits<_ForwardIterator>::value_type value_type; if (__len <= __p.second) { // The buffer is big enough to use
__destruct_n __d(0); typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
unique_ptr<value_type, __destruct_n&> __h(__p.first, __d); __destruct_n __d(0);
// Move the falses into the temporary buffer, and the trues to the front of the line unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);
// Update __first to always point to the end of the trues // Move the falses into the temporary buffer, and the trues to the front of the line
value_type* __t = __p.first; // Update __first to always point to the end of the trues
::new ((void*)__t) value_type(_Ops::__iter_move(__first)); value_type* __t = __p.first;
::new ((void*)__t) value_type(_Ops::__iter_move(__first));
__d.template __incr<value_type>();
++__t;
_ForwardIterator __i = __first;
while (++__i != __last) {
if (__pred(*__i)) {
*__first = _Ops::__iter_move(__i);
++__first;
} else {
::new ((void*)__t) value_type(_Ops::__iter_move(__i));
__d.template __incr<value_type>(); __d.template __incr<value_type>();
++__t; ++__t;
_ForwardIterator __i = __first; }
while (++__i != __last)
{
if (__pred(*__i))
{
*__first = _Ops::__iter_move(__i);
++__first;
}
else
{
::new ((void*)__t) value_type(_Ops::__iter_move(__i));
__d.template __incr<value_type>();
++__t;
}
}
// All trues now at start of range, all falses in buffer
// Move falses back into range, but don't mess up __first which points to first false
__i = __first;
for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i)
*__i = _Ops::__iter_move(__t2);
// __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
return __first;
} }
// Else not enough buffer, do in place // All trues now at start of range, all falses in buffer
// __len >= 3 // Move falses back into range, but don't mess up __first which points to first false
_ForwardIterator __m = __first; __i = __first;
_Distance __len2 = __len / 2; // __len2 >= 2 for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void)++__i)
_Ops::advance(__m, __len2); *__i = _Ops::__iter_move(__t2);
// recurse on [__first, __m), *__first know to be false // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
// F????????????????? return __first;
// f m l }
_ForwardIterator __first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( // Else not enough buffer, do in place
__first, __m, __pred, __len2, __p, __fit); // __len >= 3
// TTTFFFFF?????????? _ForwardIterator __m = __first;
// f ff m l _Distance __len2 = __len / 2; // __len2 >= 2
// recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true _Ops::advance(__m, __len2);
_ForwardIterator __m1 = __m; // recurse on [__first, __m), *__first know to be false
_ForwardIterator __second_false = __last; // F?????????????????
_Distance __len_half = __len - __len2; // f m l
while (__pred(*__m1)) _ForwardIterator __first_false =
{ std::__stable_partition_impl<_AlgPolicy, _Predicate&>(__first, __m, __pred, __len2, __p, __fit);
if (++__m1 == __last) // TTTFFFFF??????????
goto __second_half_done; // f ff m l
--__len_half; // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true
} _ForwardIterator __m1 = __m;
// TTTFFFFFTTTF?????? _ForwardIterator __second_false = __last;
// f ff m m1 l _Distance __len_half = __len - __len2;
__second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( while (__pred(*__m1)) {
__m1, __last, __pred, __len_half, __p, __fit); if (++__m1 == __last)
goto __second_half_done;
--__len_half;
}
// TTTFFFFFTTTF??????
// f ff m m1 l
__second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>(__m1, __last, __pred, __len_half, __p, __fit);
__second_half_done: __second_half_done:
// TTTFFFFFTTTTTFFFFF // TTTFFFFFTTTTTFFFFF
// f ff m sf l // f ff m sf l
return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first;
// TTTTTTTTFFFFFFFFFF // TTTTTTTTFFFFFFFFFF
// | // |
} }
template <class _AlgPolicy, class _Predicate, class _ForwardIterator> template <class _AlgPolicy, class _Predicate, class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI _ForwardIterator _LIBCPP_HIDE_FROM_ABI _ForwardIterator
__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag) {
forward_iterator_tag) typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
{ typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
const difference_type __alloc_limit = 3; // might want to make this a function of trivial assignment const difference_type __alloc_limit = 3; // might want to make this a function of trivial assignment
// Either prove all true and return __first or point to first false // Either prove all true and return __first or point to first false
while (true) while (true) {
{ if (__first == __last)
if (__first == __last) return __first;
return __first; if (!__pred(*__first))
if (!__pred(*__first)) break;
break; ++__first;
++__first; }
} // We now have a reduced range [__first, __last)
// We now have a reduced range [__first, __last) // *__first is known to be false
// *__first is known to be false difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last);
difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); pair<value_type*, ptrdiff_t> __p(0, 0);
pair<value_type*, ptrdiff_t> __p(0, 0); unique_ptr<value_type, __return_temporary_buffer> __h;
unique_ptr<value_type, __return_temporary_buffer> __h; if (__len >= __alloc_limit) {
if (__len >= __alloc_limit) // TODO: Remove the use of std::get_temporary_buffer
{ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
// TODO: Remove the use of std::get_temporary_buffer __p = std::get_temporary_buffer<value_type>(__len);
_LIBCPP_SUPPRESS_DEPRECATED_PUSH _LIBCPP_SUPPRESS_DEPRECATED_POP
__p = std::get_temporary_buffer<value_type>(__len); __h.reset(__p.first);
_LIBCPP_SUPPRESS_DEPRECATED_POP }
__h.reset(__p.first); return std::__stable_partition_impl<_AlgPolicy, _Predicate&>(
} std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag());
return std::__stable_partition_impl<_AlgPolicy, _Predicate&>(
std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag());
} }
template <class _AlgPolicy, class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair> template <class _AlgPolicy, class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair>
_BidirectionalIterator _BidirectionalIterator __stable_partition_impl(
__stable_partition_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, _BidirectionalIterator __first,
_Distance __len, _Pair __p, bidirectional_iterator_tag __bit) _BidirectionalIterator __last,
{ _Predicate __pred,
using _Ops = _IterOps<_AlgPolicy>; _Distance __len,
_Pair __p,
bidirectional_iterator_tag __bit) {
using _Ops = _IterOps<_AlgPolicy>;
// *__first is known to be false // *__first is known to be false
// *__last is known to be true // *__last is known to be true
// __len >= 2 // __len >= 2
if (__len == 2) if (__len == 2) {
{ _Ops::iter_swap(__first, __last);
_Ops::iter_swap(__first, __last); return __last;
return __last; }
if (__len == 3) {
_BidirectionalIterator __m = __first;
if (__pred(*++__m)) {
_Ops::iter_swap(__first, __m);
_Ops::iter_swap(__m, __last);
return __last;
} }
if (__len == 3) _Ops::iter_swap(__m, __last);
{ _Ops::iter_swap(__first, __m);
_BidirectionalIterator __m = __first; return __m;
if (__pred(*++__m)) }
{ if (__len <= __p.second) { // The buffer is big enough to use
_Ops::iter_swap(__first, __m); typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
_Ops::iter_swap(__m, __last); __destruct_n __d(0);
return __last; unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);
} // Move the falses into the temporary buffer, and the trues to the front of the line
_Ops::iter_swap(__m, __last); // Update __first to always point to the end of the trues
_Ops::iter_swap(__first, __m); value_type* __t = __p.first;
return __m; ::new ((void*)__t) value_type(_Ops::__iter_move(__first));
} __d.template __incr<value_type>();
if (__len <= __p.second) ++__t;
{ // The buffer is big enough to use _BidirectionalIterator __i = __first;
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; while (++__i != __last) {
__destruct_n __d(0); if (__pred(*__i)) {
unique_ptr<value_type, __destruct_n&> __h(__p.first, __d); *__first = _Ops::__iter_move(__i);
// Move the falses into the temporary buffer, and the trues to the front of the line ++__first;
// Update __first to always point to the end of the trues } else {
value_type* __t = __p.first; ::new ((void*)__t) value_type(_Ops::__iter_move(__i));
::new ((void*)__t) value_type(_Ops::__iter_move(__first));
__d.template __incr<value_type>(); __d.template __incr<value_type>();
++__t; ++__t;
_BidirectionalIterator __i = __first; }
while (++__i != __last)
{
if (__pred(*__i))
{
*__first = _Ops::__iter_move(__i);
++__first;
}
else
{
::new ((void*)__t) value_type(_Ops::__iter_move(__i));
__d.template __incr<value_type>();
++__t;
}
}
// move *__last, known to be true
*__first = _Ops::__iter_move(__i);
__i = ++__first;
// All trues now at start of range, all falses in buffer
// Move falses back into range, but don't mess up __first which points to first false
for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i)
*__i = _Ops::__iter_move(__t2);
// __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
return __first;
} }
// Else not enough buffer, do in place // move *__last, known to be true
// __len >= 4 *__first = _Ops::__iter_move(__i);
_BidirectionalIterator __m = __first; __i = ++__first;
_Distance __len2 = __len / 2; // __len2 >= 2 // All trues now at start of range, all falses in buffer
_Ops::advance(__m, __len2); // Move falses back into range, but don't mess up __first which points to first false
// recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void)++__i)
// F????????????????T *__i = _Ops::__iter_move(__t2);
// f m l // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
_BidirectionalIterator __m1 = __m; return __first;
_BidirectionalIterator __first_false = __first; }
_Distance __len_half = __len2; // Else not enough buffer, do in place
while (!__pred(*--__m1)) // __len >= 4
{ _BidirectionalIterator __m = __first;
if (__m1 == __first) _Distance __len2 = __len / 2; // __len2 >= 2
goto __first_half_done; _Ops::advance(__m, __len2);
--__len_half; // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false
} // F????????????????T
// F???TFFF?????????T // f m l
// f m1 m l _BidirectionalIterator __m1 = __m;
__first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( _BidirectionalIterator __first_false = __first;
__first, __m1, __pred, __len_half, __p, __bit); _Distance __len_half = __len2;
while (!__pred(*--__m1)) {
if (__m1 == __first)
goto __first_half_done;
--__len_half;
}
// F???TFFF?????????T
// f m1 m l
__first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>(__first, __m1, __pred, __len_half, __p, __bit);
__first_half_done: __first_half_done:
// TTTFFFFF?????????T // TTTFFFFF?????????T
// f ff m l // f ff m l
// recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true
__m1 = __m; __m1 = __m;
_BidirectionalIterator __second_false = __last; _BidirectionalIterator __second_false = __last;
++__second_false; ++__second_false;
__len_half = __len - __len2; __len_half = __len - __len2;
while (__pred(*__m1)) while (__pred(*__m1)) {
{ if (++__m1 == __last)
if (++__m1 == __last) goto __second_half_done;
goto __second_half_done; --__len_half;
--__len_half; }
} // TTTFFFFFTTTF?????T
// TTTFFFFFTTTF?????T // f ff m m1 l
// f ff m m1 l __second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>(__m1, __last, __pred, __len_half, __p, __bit);
__second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>(
__m1, __last, __pred, __len_half, __p, __bit);
__second_half_done: __second_half_done:
// TTTFFFFFTTTTTFFFFF // TTTFFFFFTTTTTFFFFF
// f ff m sf l // f ff m sf l
return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first;
// TTTTTTTTFFFFFFFFFF // TTTTTTTTFFFFFFFFFF
// | // |
} }
template <class _AlgPolicy, class _Predicate, class _BidirectionalIterator> template <class _AlgPolicy, class _Predicate, class _BidirectionalIterator>
_LIBCPP_HIDE_FROM_ABI _BidirectionalIterator _LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl(
__stable_partition_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, _BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, bidirectional_iterator_tag) {
bidirectional_iterator_tag) typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
{ typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; // Either prove all true and return __first or point to first false
const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment while (true) {
// Either prove all true and return __first or point to first false if (__first == __last)
while (true) return __first;
{ if (!__pred(*__first))
if (__first == __last) break;
return __first; ++__first;
if (!__pred(*__first)) }
break; // __first points to first false, everything prior to __first is already set.
++__first; // Either prove [__first, __last) is all false and return __first, or point __last to last true
} do {
// __first points to first false, everything prior to __first is already set. if (__first == --__last)
// Either prove [__first, __last) is all false and return __first, or point __last to last true return __first;
do } while (!__pred(*__last));
{ // We now have a reduced range [__first, __last]
if (__first == --__last) // *__first is known to be false
return __first; // *__last is known to be true
} while (!__pred(*__last)); // __len >= 2
// We now have a reduced range [__first, __last] difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1;
// *__first is known to be false pair<value_type*, ptrdiff_t> __p(0, 0);
// *__last is known to be true unique_ptr<value_type, __return_temporary_buffer> __h;
// __len >= 2 if (__len >= __alloc_limit) {
difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; // TODO: Remove the use of std::get_temporary_buffer
pair<value_type*, ptrdiff_t> __p(0, 0); _LIBCPP_SUPPRESS_DEPRECATED_PUSH
unique_ptr<value_type, __return_temporary_buffer> __h; __p = std::get_temporary_buffer<value_type>(__len);
if (__len >= __alloc_limit) _LIBCPP_SUPPRESS_DEPRECATED_POP
{ __h.reset(__p.first);
// TODO: Remove the use of std::get_temporary_buffer }
_LIBCPP_SUPPRESS_DEPRECATED_PUSH return std::__stable_partition_impl<_AlgPolicy, _Predicate&>(
__p = std::get_temporary_buffer<value_type>(__len); std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag());
_LIBCPP_SUPPRESS_DEPRECATED_POP
__h.reset(__p.first);
}
return std::__stable_partition_impl<_AlgPolicy, _Predicate&>(
std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag());
} }
template <class _AlgPolicy, class _Predicate, class _ForwardIterator, class _IterCategory> template <class _AlgPolicy, class _Predicate, class _ForwardIterator, class _IterCategory>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _ForwardIterator __stable_partition(
_ForwardIterator __stable_partition(
_ForwardIterator __first, _ForwardIterator __last, _Predicate&& __pred, _IterCategory __iter_category) { _ForwardIterator __first, _ForwardIterator __last, _Predicate&& __pred, _IterCategory __iter_category) {
return std::__stable_partition_impl<_AlgPolicy, __remove_cvref_t<_Predicate>&>( return std::__stable_partition_impl<_AlgPolicy, __remove_cvref_t<_Predicate>&>(
std::move(__first), std::move(__last), __pred, __iter_category); std::move(__first), std::move(__last), __pred, __iter_category);
} }
template <class _ForwardIterator, class _Predicate> template <class _ForwardIterator, class _Predicate>
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
_ForwardIterator stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
{
using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category;
return std::__stable_partition<_ClassicAlgPolicy, _Predicate&>( return std::__stable_partition<_ClassicAlgPolicy, _Predicate&>(
std::move(__first), std::move(__last), __pred, _IterCategory()); std::move(__first), std::move(__last), __pred, _IterCategory());

View File

@ -32,9 +32,11 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator> template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI void __insertion_sort_move(
void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1, _BidirectionalIterator __first1,
typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) { _BidirectionalIterator __last1,
typename iterator_traits<_BidirectionalIterator>::value_type* __first2,
_Compare __comp) {
using _Ops = _IterOps<_AlgPolicy>; using _Ops = _IterOps<_AlgPolicy>;
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
@ -63,200 +65,187 @@ void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterat
} }
template <class _AlgPolicy, class _Compare, class _InputIterator1, class _InputIterator2> template <class _AlgPolicy, class _Compare, class _InputIterator1, class _InputIterator2>
_LIBCPP_HIDE_FROM_ABI void _LIBCPP_HIDE_FROM_ABI void __merge_move_construct(
__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator1 __first1,
_InputIterator2 __first2, _InputIterator2 __last2, _InputIterator1 __last1,
typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp) _InputIterator2 __first2,
{ _InputIterator2 __last2,
using _Ops = _IterOps<_AlgPolicy>; typename iterator_traits<_InputIterator1>::value_type* __result,
_Compare __comp) {
using _Ops = _IterOps<_AlgPolicy>;
typedef typename iterator_traits<_InputIterator1>::value_type value_type; typedef typename iterator_traits<_InputIterator1>::value_type value_type;
__destruct_n __d(0); __destruct_n __d(0);
unique_ptr<value_type, __destruct_n&> __h(__result, __d); unique_ptr<value_type, __destruct_n&> __h(__result, __d);
for (; true; ++__result) for (; true; ++__result) {
{ if (__first1 == __last1) {
if (__first1 == __last1) for (; __first2 != __last2; ++__first2, (void)++__result, __d.template __incr<value_type>())
{ ::new ((void*)__result) value_type(_Ops::__iter_move(__first2));
for (; __first2 != __last2; ++__first2, (void) ++__result, __d.template __incr<value_type>()) __h.release();
::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); return;
__h.release();
return;
}
if (__first2 == __last2)
{
for (; __first1 != __last1; ++__first1, (void) ++__result, __d.template __incr<value_type>())
::new ((void*)__result) value_type(_Ops::__iter_move(__first1));
__h.release();
return;
}
if (__comp(*__first2, *__first1))
{
::new ((void*)__result) value_type(_Ops::__iter_move(__first2));
__d.template __incr<value_type>();
++__first2;
}
else
{
::new ((void*)__result) value_type(_Ops::__iter_move(__first1));
__d.template __incr<value_type>();
++__first1;
}
} }
if (__first2 == __last2) {
for (; __first1 != __last1; ++__first1, (void)++__result, __d.template __incr<value_type>())
::new ((void*)__result) value_type(_Ops::__iter_move(__first1));
__h.release();
return;
}
if (__comp(*__first2, *__first1)) {
::new ((void*)__result) value_type(_Ops::__iter_move(__first2));
__d.template __incr<value_type>();
++__first2;
} else {
::new ((void*)__result) value_type(_Ops::__iter_move(__first1));
__d.template __incr<value_type>();
++__first1;
}
}
} }
template <class _AlgPolicy, class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> template <class _AlgPolicy, class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
_LIBCPP_HIDE_FROM_ABI void _LIBCPP_HIDE_FROM_ABI void __merge_move_assign(
__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator1 __first1,
_InputIterator2 __first2, _InputIterator2 __last2, _InputIterator1 __last1,
_OutputIterator __result, _Compare __comp) _InputIterator2 __first2,
{ _InputIterator2 __last2,
using _Ops = _IterOps<_AlgPolicy>; _OutputIterator __result,
_Compare __comp) {
using _Ops = _IterOps<_AlgPolicy>;
for (; __first1 != __last1; ++__result) for (; __first1 != __last1; ++__result) {
{ if (__first2 == __last2) {
if (__first2 == __last2) for (; __first1 != __last1; ++__first1, (void)++__result)
{ *__result = _Ops::__iter_move(__first1);
for (; __first1 != __last1; ++__first1, (void) ++__result) return;
*__result = _Ops::__iter_move(__first1);
return;
}
if (__comp(*__first2, *__first1))
{
*__result = _Ops::__iter_move(__first2);
++__first2;
}
else
{
*__result = _Ops::__iter_move(__first1);
++__first1;
}
} }
for (; __first2 != __last2; ++__first2, (void) ++__result) if (__comp(*__first2, *__first1)) {
*__result = _Ops::__iter_move(__first2); *__result = _Ops::__iter_move(__first2);
++__first2;
} else {
*__result = _Ops::__iter_move(__first1);
++__first1;
}
}
for (; __first2 != __last2; ++__first2, (void)++__result)
*__result = _Ops::__iter_move(__first2);
} }
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
void void __stable_sort(_RandomAccessIterator __first,
__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _RandomAccessIterator __last,
typename iterator_traits<_RandomAccessIterator>::difference_type __len, _Compare __comp,
typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size); typename iterator_traits<_RandomAccessIterator>::difference_type __len,
typename iterator_traits<_RandomAccessIterator>::value_type* __buff,
ptrdiff_t __buff_size);
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
void void __stable_sort_move(_RandomAccessIterator __first1,
__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp, _RandomAccessIterator __last1,
typename iterator_traits<_RandomAccessIterator>::difference_type __len, _Compare __comp,
typename iterator_traits<_RandomAccessIterator>::value_type* __first2) typename iterator_traits<_RandomAccessIterator>::difference_type __len,
{ typename iterator_traits<_RandomAccessIterator>::value_type* __first2) {
using _Ops = _IterOps<_AlgPolicy>; using _Ops = _IterOps<_AlgPolicy>;
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
switch (__len) switch (__len) {
{ case 0:
case 0: return;
return; case 1:
case 1: ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1));
::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); return;
return; case 2:
case 2: __destruct_n __d(0);
__destruct_n __d(0); unique_ptr<value_type, __destruct_n&> __h2(__first2, __d);
unique_ptr<value_type, __destruct_n&> __h2(__first2, __d); if (__comp(*--__last1, *__first1)) {
if (__comp(*--__last1, *__first1)) ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1));
{ __d.template __incr<value_type>();
::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); ++__first2;
__d.template __incr<value_type>(); ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1));
++__first2; } else {
::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1));
} __d.template __incr<value_type>();
else ++__first2;
{ ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1));
::new ((void*)__first2) value_type(_Ops::__iter_move(__first1));
__d.template __incr<value_type>();
++__first2;
::new ((void*)__first2) value_type(_Ops::__iter_move(__last1));
}
__h2.release();
return;
} }
if (__len <= 8) __h2.release();
{ return;
std::__insertion_sort_move<_AlgPolicy, _Compare>(__first1, __last1, __first2, __comp); }
return; if (__len <= 8) {
} std::__insertion_sort_move<_AlgPolicy, _Compare>(__first1, __last1, __first2, __comp);
typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; return;
_RandomAccessIterator __m = __first1 + __l2; }
std::__stable_sort<_AlgPolicy, _Compare>(__first1, __m, __comp, __l2, __first2, __l2); typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;
std::__stable_sort<_AlgPolicy, _Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); _RandomAccessIterator __m = __first1 + __l2;
std::__merge_move_construct<_AlgPolicy, _Compare>(__first1, __m, __m, __last1, __first2, __comp); std::__stable_sort<_AlgPolicy, _Compare>(__first1, __m, __comp, __l2, __first2, __l2);
std::__stable_sort<_AlgPolicy, _Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2);
std::__merge_move_construct<_AlgPolicy, _Compare>(__first1, __m, __m, __last1, __first2, __comp);
} }
template <class _Tp> template <class _Tp>
struct __stable_sort_switch struct __stable_sort_switch {
{ static const unsigned value = 128 * is_trivially_copy_assignable<_Tp>::value;
static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value;
}; };
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
void void __stable_sort(_RandomAccessIterator __first,
__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _RandomAccessIterator __last,
typename iterator_traits<_RandomAccessIterator>::difference_type __len, _Compare __comp,
typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size) typename iterator_traits<_RandomAccessIterator>::difference_type __len,
{ typename iterator_traits<_RandomAccessIterator>::value_type* __buff,
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; ptrdiff_t __buff_size) {
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
switch (__len) typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
{ switch (__len) {
case 0: case 0:
case 1: case 1:
return; return;
case 2: case 2:
if (__comp(*--__last, *__first)) if (__comp(*--__last, *__first))
_IterOps<_AlgPolicy>::iter_swap(__first, __last); _IterOps<_AlgPolicy>::iter_swap(__first, __last);
return; return;
} }
if (__len <= static_cast<difference_type>(__stable_sort_switch<value_type>::value)) if (__len <= static_cast<difference_type>(__stable_sort_switch<value_type>::value)) {
{ std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp);
std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp); return;
return; }
} typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;
typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; _RandomAccessIterator __m = __first + __l2;
_RandomAccessIterator __m = __first + __l2; if (__len <= __buff_size) {
if (__len <= __buff_size) __destruct_n __d(0);
{ unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
__destruct_n __d(0); std::__stable_sort_move<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff);
unique_ptr<value_type, __destruct_n&> __h2(__buff, __d); __d.__set(__l2, (value_type*)nullptr);
std::__stable_sort_move<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff); std::__stable_sort_move<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff + __l2);
__d.__set(__l2, (value_type*)nullptr); __d.__set(__len, (value_type*)nullptr);
std::__stable_sort_move<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); std::__merge_move_assign<_AlgPolicy, _Compare>(
__d.__set(__len, (value_type*)nullptr); __buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp);
std::__merge_move_assign<_AlgPolicy, _Compare>( // std::__merge<_Compare>(move_iterator<value_type*>(__buff),
__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); // move_iterator<value_type*>(__buff + __l2),
// std::__merge<_Compare>(move_iterator<value_type*>(__buff), // move_iterator<_RandomAccessIterator>(__buff + __l2),
// move_iterator<value_type*>(__buff + __l2), // move_iterator<_RandomAccessIterator>(__buff + __len),
// move_iterator<_RandomAccessIterator>(__buff + __l2), // __first, __comp);
// move_iterator<_RandomAccessIterator>(__buff + __len), return;
// __first, __comp); }
return; std::__stable_sort<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff, __buff_size);
} std::__stable_sort<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size);
std::__stable_sort<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff, __buff_size); std::__inplace_merge<_AlgPolicy>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size);
std::__stable_sort<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size);
std::__inplace_merge<_AlgPolicy>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size);
} }
template <class _AlgPolicy, class _RandomAccessIterator, class _Compare> template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI void
void __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
difference_type __len = __last - __first; difference_type __len = __last - __first;
pair<value_type*, ptrdiff_t> __buf(0, 0); pair<value_type*, ptrdiff_t> __buf(0, 0);
unique_ptr<value_type, __return_temporary_buffer> __h; unique_ptr<value_type, __return_temporary_buffer> __h;
if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) { if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value)) {
// TODO: Remove the use of std::get_temporary_buffer // TODO: Remove the use of std::get_temporary_buffer
_LIBCPP_SUPPRESS_DEPRECATED_PUSH _LIBCPP_SUPPRESS_DEPRECATED_PUSH
__buf = std::get_temporary_buffer<value_type>(__len); __buf = std::get_temporary_buffer<value_type>(__len);
_LIBCPP_SUPPRESS_DEPRECATED_POP _LIBCPP_SUPPRESS_DEPRECATED_POP
__h.reset(__buf.first); __h.reset(__buf.first);
} }
std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second); std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second);
@ -264,14 +253,13 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
} }
template <class _RandomAccessIterator, class _Compare> template <class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI void
void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
std::__stable_sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); std::__stable_sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp);
} }
template <class _RandomAccessIterator> template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::stable_sort(__first, __last, __less<>()); std::stable_sort(__first, __last, __less<>());
} }

View File

@ -22,8 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// 2+2 iterators: the shorter size will be used. // 2+2 iterators: the shorter size will be used.
template <class _AlgPolicy, class _ForwardIterator1, class _Sentinel1, class _ForwardIterator2, class _Sentinel2> template <class _AlgPolicy, class _ForwardIterator1, class _Sentinel1, class _ForwardIterator2, class _Sentinel2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator1, _ForwardIterator2>
pair<_ForwardIterator1, _ForwardIterator2>
__swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _Sentinel2 __last2) { __swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _Sentinel2 __last2) {
while (__first1 != __last1 && __first2 != __last2) { while (__first1 != __last1 && __first2 != __last2) {
_IterOps<_AlgPolicy>::iter_swap(__first1, __first2); _IterOps<_AlgPolicy>::iter_swap(__first1, __first2);
@ -36,8 +35,7 @@ __swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2
// 2+1 iterators: size2 >= size1. // 2+1 iterators: size2 >= size1.
template <class _AlgPolicy, class _ForwardIterator1, class _Sentinel1, class _ForwardIterator2> template <class _AlgPolicy, class _ForwardIterator1, class _Sentinel1, class _ForwardIterator2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator1, _ForwardIterator2>
pair<_ForwardIterator1, _ForwardIterator2>
__swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2) { __swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2) {
while (__first1 != __last1) { while (__first1 != __last1) {
_IterOps<_AlgPolicy>::iter_swap(__first1, __first2); _IterOps<_AlgPolicy>::iter_swap(__first1, __first2);
@ -51,8 +49,7 @@ __swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2
template <class _ForwardIterator1, class _ForwardIterator2> template <class _ForwardIterator1, class _ForwardIterator2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator2 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator2
swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
return std::__swap_ranges<_ClassicAlgPolicy>( return std::__swap_ranges<_ClassicAlgPolicy>(std::move(__first1), std::move(__last1), std::move(__first2)).second;
std::move(__first1), std::move(__last1), std::move(__first2)).second;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -18,24 +18,23 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _OutputIterator, class _UnaryOperation> template <class _InputIterator, class _OutputIterator, class _UnaryOperation>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
_OutputIterator transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) {
transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) for (; __first != __last; ++__first, (void)++__result)
{ *__result = __op(*__first);
for (; __first != __last; ++__first, (void) ++__result) return __result;
*__result = __op(*__first);
return __result;
} }
template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _BinaryOperation> template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _BinaryOperation>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator transform(
_OutputIterator _InputIterator1 __first1,
transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator1 __last1,
_OutputIterator __result, _BinaryOperation __binary_op) _InputIterator2 __first2,
{ _OutputIterator __result,
for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result) _BinaryOperation __binary_op) {
*__result = __binary_op(*__first1, *__first2); for (; __first1 != __last1; ++__first1, (void)++__first2, ++__result)
return __result; *__result = __binary_op(*__first1, *__first2);
return __result;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -20,7 +20,7 @@
#if _LIBCPP_STD_VER >= 20 #if _LIBCPP_STD_VER >= 20
_LIBCPP_PUSH_MACROS _LIBCPP_PUSH_MACROS
#include <__undef_macros> # include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
@ -41,16 +41,12 @@ private:
public: public:
using result_type = invoke_result_t<_Gen&>; using result_type = invoke_result_t<_Gen&>;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI static constexpr auto min() { return __remove_cvref_t<_Gen>::min(); }
static constexpr auto min() { return __remove_cvref_t<_Gen>::min(); } _LIBCPP_HIDE_FROM_ABI static constexpr auto max() { return __remove_cvref_t<_Gen>::max(); }
_LIBCPP_HIDE_FROM_ABI
static constexpr auto max() { return __remove_cvref_t<_Gen>::max(); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI constexpr explicit _ClassicGenAdaptor(_Gen& __g) : __gen_(__g) {}
constexpr explicit _ClassicGenAdaptor(_Gen& __g) : __gen_(__g) {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI constexpr auto operator()() const { return __gen_(); }
constexpr auto operator()() const { return __gen_(); }
}; };
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -57,11 +57,11 @@ struct __unwrap_iter_impl<_Iter, true> {
} }
}; };
template<class _Iter, template <class _Iter,
class _Impl = __unwrap_iter_impl<_Iter>, class _Impl = __unwrap_iter_impl<_Iter>,
__enable_if_t<is_copy_constructible<_Iter>::value, int> = 0> __enable_if_t<is_copy_constructible<_Iter>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 decltype(_Impl::__unwrap(std::declval<_Iter>()))
decltype(_Impl::__unwrap(std::declval<_Iter>())) __unwrap_iter(_Iter __i) _NOEXCEPT { __unwrap_iter(_Iter __i) _NOEXCEPT {
return _Impl::__unwrap(__i); return _Impl::__unwrap(__i);
} }

File diff suppressed because it is too large Load Diff

View File

@ -29,114 +29,109 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value> template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
struct __atomic_base // false struct __atomic_base // false
{ {
mutable __cxx_atomic_impl<_Tp> __a_; mutable __cxx_atomic_impl<_Tp> __a_;
#if _LIBCPP_STD_VER >= 17 #if _LIBCPP_STD_VER >= 17
static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value; static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value;
#endif #endif
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const volatile _NOEXCEPT {
bool is_lock_free() const volatile _NOEXCEPT return __cxx_atomic_is_lock_free(sizeof(__cxx_atomic_impl<_Tp>));
{return __cxx_atomic_is_lock_free(sizeof(__cxx_atomic_impl<_Tp>));} }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const _NOEXCEPT {
bool is_lock_free() const _NOEXCEPT return static_cast<__atomic_base const volatile*>(this)->is_lock_free();
{return static_cast<__atomic_base const volatile*>(this)->is_lock_free();} }
_LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
std::__cxx_atomic_store(std::addressof(__a_), __d, __m); std::__cxx_atomic_store(std::addressof(__a_), __d, __m);
} }
_LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
std::__cxx_atomic_store(std::addressof(__a_), __d, __m); std::__cxx_atomic_store(std::addressof(__a_), __d, __m);
} }
_LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
return std::__cxx_atomic_load(std::addressof(__a_), __m); return std::__cxx_atomic_load(std::addressof(__a_), __m);
} }
_LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
return std::__cxx_atomic_load(std::addressof(__a_), __m); return std::__cxx_atomic_load(std::addressof(__a_), __m);
} }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI operator _Tp() const volatile _NOEXCEPT { return load(); }
operator _Tp() const volatile _NOEXCEPT {return load();} _LIBCPP_HIDE_FROM_ABI operator _Tp() const _NOEXCEPT { return load(); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
operator _Tp() const _NOEXCEPT {return load();} return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);
_LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { }
return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m); _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
} return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);
_LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { }
return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m); _LIBCPP_HIDE_FROM_ABI bool
} compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
_LIBCPP_HIDE_FROM_ABI bool _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { }
return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f); _LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
} _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
_LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { }
return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f); _LIBCPP_HIDE_FROM_ABI bool
} compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
_LIBCPP_HIDE_FROM_ABI bool _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { }
return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f); _LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
} _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
_LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { }
return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f); _LIBCPP_HIDE_FROM_ABI bool
} compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
_LIBCPP_HIDE_FROM_ABI bool return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { }
return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m); _LIBCPP_HIDE_FROM_ABI bool
} compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
_LIBCPP_HIDE_FROM_ABI bool return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { }
return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m); _LIBCPP_HIDE_FROM_ABI bool
} compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
_LIBCPP_HIDE_FROM_ABI bool return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { }
return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m); _LIBCPP_HIDE_FROM_ABI bool
} compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
_LIBCPP_HIDE_FROM_ABI bool return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { }
return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const
volatile _NOEXCEPT { volatile _NOEXCEPT {
std::__cxx_atomic_wait(std::addressof(__a_), __v, __m); std::__cxx_atomic_wait(std::addressof(__a_), __v, __m);
} }
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT { wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
std::__cxx_atomic_wait(std::addressof(__a_), __v, __m); std::__cxx_atomic_wait(std::addressof(__a_), __v, __m);
} }
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
std::__cxx_atomic_notify_one(std::addressof(__a_)); std::__cxx_atomic_notify_one(std::addressof(__a_));
} }
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT {
std::__cxx_atomic_notify_one(std::addressof(__a_)); std::__cxx_atomic_notify_one(std::addressof(__a_));
} }
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
std::__cxx_atomic_notify_all(std::addressof(__a_)); std::__cxx_atomic_notify_all(std::addressof(__a_));
} }
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT {
std::__cxx_atomic_notify_all(std::addressof(__a_)); std::__cxx_atomic_notify_all(std::addressof(__a_));
} }
#if _LIBCPP_STD_VER >= 20 #if _LIBCPP_STD_VER >= 20
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_HIDE_FROM_ABI constexpr __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
__atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
#else #else
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI __atomic_base() _NOEXCEPT = default;
__atomic_base() _NOEXCEPT = default;
#endif #endif
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
__atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
__atomic_base(const __atomic_base&) = delete; __atomic_base(const __atomic_base&) = delete;
}; };
#if _LIBCPP_STD_VER >= 17 #if _LIBCPP_STD_VER >= 17
@ -147,84 +142,62 @@ _LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
// atomic<Integral> // atomic<Integral>
template <class _Tp> template <class _Tp>
struct __atomic_base<_Tp, true> struct __atomic_base<_Tp, true> : public __atomic_base<_Tp, false> {
: public __atomic_base<_Tp, false> using __base = __atomic_base<_Tp, false>;
{
using __base = __atomic_base<_Tp, false>;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __atomic_base() _NOEXCEPT = default;
__atomic_base() _NOEXCEPT = default;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
_LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
_LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
} }
_LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
} }
_LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
} }
_LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
} }
_LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m); return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);
} }
_LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m); return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);
} }
_LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m); return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);
} }
_LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m); return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);
} }
_LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m); return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);
} }
_LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m); return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);
} }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Tp operator++(int) volatile _NOEXCEPT { return fetch_add(_Tp(1)); }
_Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} _LIBCPP_HIDE_FROM_ABI _Tp operator++(int) _NOEXCEPT { return fetch_add(_Tp(1)); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Tp operator--(int) volatile _NOEXCEPT { return fetch_sub(_Tp(1)); }
_Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));} _LIBCPP_HIDE_FROM_ABI _Tp operator--(int) _NOEXCEPT { return fetch_sub(_Tp(1)); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Tp operator++() volatile _NOEXCEPT { return fetch_add(_Tp(1)) + _Tp(1); }
_Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));} _LIBCPP_HIDE_FROM_ABI _Tp operator++() _NOEXCEPT { return fetch_add(_Tp(1)) + _Tp(1); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Tp operator--() volatile _NOEXCEPT { return fetch_sub(_Tp(1)) - _Tp(1); }
_Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));} _LIBCPP_HIDE_FROM_ABI _Tp operator--() _NOEXCEPT { return fetch_sub(_Tp(1)) - _Tp(1); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) volatile _NOEXCEPT { return fetch_add(__op) + __op; }
_Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) _NOEXCEPT { return fetch_add(__op) + __op; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) volatile _NOEXCEPT { return fetch_sub(__op) - __op; }
_Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) _NOEXCEPT { return fetch_sub(__op) - __op; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Tp operator&=(_Tp __op) volatile _NOEXCEPT { return fetch_and(__op) & __op; }
_Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} _LIBCPP_HIDE_FROM_ABI _Tp operator&=(_Tp __op) _NOEXCEPT { return fetch_and(__op) & __op; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Tp operator|=(_Tp __op) volatile _NOEXCEPT { return fetch_or(__op) | __op; }
_Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} _LIBCPP_HIDE_FROM_ABI _Tp operator|=(_Tp __op) _NOEXCEPT { return fetch_or(__op) | __op; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __op) volatile _NOEXCEPT { return fetch_xor(__op) ^ __op; }
_Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} _LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __op) _NOEXCEPT { return fetch_xor(__op) ^ __op; }
_LIBCPP_HIDE_FROM_ABI
_Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
_LIBCPP_HIDE_FROM_ABI
_Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
_LIBCPP_HIDE_FROM_ABI
_Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
_LIBCPP_HIDE_FROM_ABI
_Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
_LIBCPP_HIDE_FROM_ABI
_Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
_LIBCPP_HIDE_FROM_ABI
_Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
_LIBCPP_HIDE_FROM_ABI
_Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
_LIBCPP_HIDE_FROM_ABI
_Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
_LIBCPP_HIDE_FROM_ABI
_Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
}; };
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -24,205 +24,135 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
struct atomic_flag struct atomic_flag {
{ __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
__cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
{return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
{return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
{return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
{return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
{__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
{__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} }
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const
void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT volatile _NOEXCEPT {
{__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} __cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI }
void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
{__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI __cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
void notify_one() volatile _NOEXCEPT }
{__cxx_atomic_notify_one(&__a_);} _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI __cxx_atomic_notify_one(&__a_);
void notify_one() _NOEXCEPT }
{__cxx_atomic_notify_one(&__a_);} _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { __cxx_atomic_notify_one(&__a_); }
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
void notify_all() volatile _NOEXCEPT __cxx_atomic_notify_all(&__a_);
{__cxx_atomic_notify_all(&__a_);} }
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { __cxx_atomic_notify_all(&__a_); }
void notify_all() _NOEXCEPT
{__cxx_atomic_notify_all(&__a_);}
#if _LIBCPP_STD_VER >= 20 #if _LIBCPP_STD_VER >= 20
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_HIDE_FROM_ABI constexpr atomic_flag() _NOEXCEPT : __a_(false) {}
atomic_flag() _NOEXCEPT : __a_(false) {}
#else #else
atomic_flag() _NOEXCEPT = default; atomic_flag() _NOEXCEPT = default;
#endif #endif
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
atomic_flag(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) volatile = delete;
atomic_flag(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) volatile = delete;
}; };
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); }
bool
atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const atomic_flag* __o) _NOEXCEPT { return __o->test(); }
{
return __o->test(); inline _LIBCPP_HIDE_FROM_ABI bool
atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
return __o->test(__m);
} }
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT {
bool return __o->test(__m);
atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
{
return __o->test();
} }
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT {
bool return __o->test_and_set();
atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
{
return __o->test(__m);
} }
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT { return __o->test_and_set(); }
bool
atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT inline _LIBCPP_HIDE_FROM_ABI bool
{ atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
return __o->test(__m); return __o->test_and_set(__m);
} }
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {
bool return __o->test_and_set(__m);
atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
{
return __o->test_and_set();
} }
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT { __o->clear(); }
bool
atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(atomic_flag* __o) _NOEXCEPT { __o->clear(); }
{
return __o->test_and_set(); inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
__o->clear(__m);
} }
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {
bool __o->clear(__m);
atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
{
return __o->test_and_set(__m);
} }
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
bool atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT {
atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT __o->wait(__v);
{
return __o->test_and_set(__m);
} }
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
void atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT {
atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT __o->wait(__v);
{
__o->clear();
} }
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
void atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
atomic_flag_clear(atomic_flag* __o) _NOEXCEPT __o->wait(__v, __m);
{
__o->clear();
} }
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
void atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT __o->wait(__v, __m);
{
__o->clear(__m);
} }
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
void atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT {
atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT __o->notify_one();
{
__o->clear(__m);
} }
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT {
void __o->notify_one();
atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
{
__o->wait(__v);
} }
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
void atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT {
atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT __o->notify_all();
{
__o->wait(__v);
} }
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT {
void __o->notify_all();
atomic_flag_wait_explicit(const volatile atomic_flag* __o,
bool __v, memory_order __m) _NOEXCEPT
{
__o->wait(__v, __m);
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
void
atomic_flag_wait_explicit(const atomic_flag* __o,
bool __v, memory_order __m) _NOEXCEPT
{
__o->wait(__v, __m);
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
void
atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
{
__o->notify_one();
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
void
atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
{
__o->notify_one();
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
void
atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
{
__o->notify_all();
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
void
atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
{
__o->notify_all();
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -16,33 +16,33 @@
#endif #endif
#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE) #if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE # define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE # define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
#ifndef _LIBCPP_HAS_NO_CHAR8_T # ifndef _LIBCPP_HAS_NO_CHAR8_T
# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE # define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
#endif # endif
# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE # define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE # define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE # define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE # define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE # define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE # define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE # define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE # define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE) #elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE # define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE # define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
#ifndef _LIBCPP_HAS_NO_CHAR8_T # ifndef _LIBCPP_HAS_NO_CHAR8_T
# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE # define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
#endif # endif
# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE # define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE # define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE # define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE # define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE # define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE # define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE # define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE # define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
#endif #endif
#endif // _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H #endif // _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H

View File

@ -34,77 +34,73 @@ _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*); _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t); _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*); _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*); __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*); _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t); __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
__libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
template <class _Atp, class _Fn> template <class _Atp, class _Fn>
struct __libcpp_atomic_wait_backoff_impl { struct __libcpp_atomic_wait_backoff_impl {
_Atp* __a; _Atp* __a;
_Fn __test_fn; _Fn __test_fn;
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_AVAILABILITY_SYNC
_LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const _LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const {
{ if (__elapsed > chrono::microseconds(64)) {
if(__elapsed > chrono::microseconds(64)) auto const __monitor = std::__libcpp_atomic_monitor(__a);
{ if (__test_fn())
auto const __monitor = std::__libcpp_atomic_monitor(__a); return true;
if(__test_fn()) std::__libcpp_atomic_wait(__a, __monitor);
return true; } else if (__elapsed > chrono::microseconds(4))
std::__libcpp_atomic_wait(__a, __monitor); __libcpp_thread_yield();
} else {
else if(__elapsed > chrono::microseconds(4)) } // poll
__libcpp_thread_yield(); return false;
else }
{} // poll
return false;
}
}; };
template <class _Atp, class _Fn> template <class _Atp, class _Fn>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Fn&& __test_fn) {
_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn) __libcpp_atomic_wait_backoff_impl<_Atp, __decay_t<_Fn> > __backoff_fn = {__a, __test_fn};
{ return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
__libcpp_atomic_wait_backoff_impl<_Atp, __decay_t<_Fn> > __backoff_fn = {__a, __test_fn};
return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
} }
#else // _LIBCPP_HAS_NO_THREADS #else // _LIBCPP_HAS_NO_THREADS
template <class _Tp> template <class _Tp>
_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { } _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) {}
template <class _Tp> template <class _Tp>
_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { } _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) {}
template <class _Atp, class _Fn> template <class _Atp, class _Fn>
_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn) _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp*, _Fn&& __test_fn) {
{ return std::__libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy());
return std::__libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy());
} }
#endif // _LIBCPP_HAS_NO_THREADS #endif // _LIBCPP_HAS_NO_THREADS
template <typename _Tp> _LIBCPP_HIDE_FROM_ABI template <typename _Tp>
bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) { _LIBCPP_HIDE_FROM_ABI bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
return std::memcmp(std::addressof(__lhs), std::addressof(__rhs), sizeof(_Tp)) == 0; return std::memcmp(std::addressof(__lhs), std::addressof(__rhs), sizeof(_Tp)) == 0;
} }
template <class _Atp, class _Tp> template <class _Atp, class _Tp>
struct __cxx_atomic_wait_test_fn_impl { struct __cxx_atomic_wait_test_fn_impl {
_Atp* __a; _Atp* __a;
_Tp __val; _Tp __val;
memory_order __order; memory_order __order;
_LIBCPP_HIDE_FROM_ABI bool operator()() const _LIBCPP_HIDE_FROM_ABI bool operator()() const {
{ return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val);
return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val); }
}
}; };
template <class _Atp, class _Tp> template <class _Atp, class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool
_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order) __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order) {
{ __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
__cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order}; return std::__cxx_atomic_wait(__a, __test_fn);
return std::__cxx_atomic_wait(__a, __test_fn);
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -15,20 +15,16 @@
# pragma GCC system_header # pragma GCC system_header
#endif #endif
#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \ #define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
_LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \ _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || __m == memory_order_acquire || __m == memory_order_acq_rel, \
__m == memory_order_acquire || \ "memory order argument to atomic operation is invalid")
__m == memory_order_acq_rel, \
"memory order argument to atomic operation is invalid")
#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \ #define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
_LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \ _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || __m == memory_order_acq_rel, \
__m == memory_order_acq_rel, \ "memory order argument to atomic operation is invalid")
"memory order argument to atomic operation is invalid")
#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \ #define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
_LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \ _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || __f == memory_order_acq_rel, \
__f == memory_order_acq_rel, \ "memory order argument to atomic operation is invalid")
"memory order argument to atomic operation is invalid")
#endif // _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H #endif // _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H

View File

@ -20,9 +20,9 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__)) #if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
using __cxx_contention_t = int32_t; using __cxx_contention_t = int32_t;
#else #else
using __cxx_contention_t = int64_t; using __cxx_contention_t = int64_t;
#endif // __linux__ || (_AIX && !__64BIT__) #endif // __linux__ || (_AIX && !__64BIT__)
using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>; using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;

File diff suppressed because it is too large Load Diff

View File

@ -19,19 +19,9 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI void atomic_thread_fence(memory_order __m) _NOEXCEPT { __cxx_atomic_thread_fence(__m); }
void
atomic_thread_fence(memory_order __m) _NOEXCEPT
{
__cxx_atomic_thread_fence(__m);
}
inline _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_HIDE_FROM_ABI void atomic_signal_fence(memory_order __m) _NOEXCEPT { __cxx_atomic_signal_fence(__m); }
void
atomic_signal_fence(memory_order __m) _NOEXCEPT
{
__cxx_atomic_signal_fence(__m);
}
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -18,10 +18,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp> template <class _Tp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Tp kill_dependency(_Tp __y) _NOEXCEPT {
_Tp kill_dependency(_Tp __y) _NOEXCEPT return __y;
{
return __y;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -22,14 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// Figure out what the underlying type for `memory_order` would be if it were // Figure out what the underlying type for `memory_order` would be if it were
// declared as an unscoped enum (accounting for -fshort-enums). Use this result // declared as an unscoped enum (accounting for -fshort-enums). Use this result
// to pin the underlying type in C++20. // to pin the underlying type in C++20.
enum __legacy_memory_order { enum __legacy_memory_order { __mo_relaxed, __mo_consume, __mo_acquire, __mo_release, __mo_acq_rel, __mo_seq_cst };
__mo_relaxed,
__mo_consume,
__mo_acquire,
__mo_release,
__mo_acq_rel,
__mo_seq_cst
};
using __memory_order_underlying_t = underlying_type<__legacy_memory_order>::type; using __memory_order_underlying_t = underlying_type<__legacy_memory_order>::type;
@ -45,7 +38,7 @@ enum class memory_order : __memory_order_underlying_t {
}; };
static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value), static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
"unexpected underlying type for std::memory_order"); "unexpected underlying type for std::memory_order");
inline constexpr auto memory_order_relaxed = memory_order::relaxed; inline constexpr auto memory_order_relaxed = memory_order::relaxed;
inline constexpr auto memory_order_consume = memory_order::consume; inline constexpr auto memory_order_consume = memory_order::consume;

View File

@ -64,25 +64,22 @@
// //
// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability // [1]: https://clang.llvm.org/docs/AttributeReference.html#availability
// For backwards compatibility, allow users to define _LIBCPP_DISABLE_AVAILABILITY // For backwards compatibility, allow users to define _LIBCPP_DISABLE_AVAILABILITY
// for a while. // for a while.
#if defined(_LIBCPP_DISABLE_AVAILABILITY) #if defined(_LIBCPP_DISABLE_AVAILABILITY)
# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) # if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS # define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS
# endif # endif
#endif #endif
// Availability markup is disabled when building the library, or when the compiler // Availability markup is disabled when building the library, or when the compiler
// doesn't support the proper attributes. // doesn't support the proper attributes.
#if defined(_LIBCPP_BUILDING_LIBRARY) || \ #if defined(_LIBCPP_BUILDING_LIBRARY) || defined(_LIBCXXABI_BUILDING_LIBRARY) || \
defined(_LIBCXXABI_BUILDING_LIBRARY) || \ !__has_feature(attribute_availability_with_strict) || !__has_feature(attribute_availability_in_templates) || \
!__has_feature(attribute_availability_with_strict) || \
!__has_feature(attribute_availability_in_templates) || \
!__has_extension(pragma_clang_attribute_external_declaration) !__has_extension(pragma_clang_attribute_external_declaration)
# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) # if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS # define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS
# endif # endif
#endif #endif
#if defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) #if defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
@ -160,7 +157,7 @@
# define _LIBCPP_AVAILABILITY_HAS_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_HAS_BAD_OPTIONAL_ACCESS # define _LIBCPP_AVAILABILITY_HAS_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_HAS_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_HAS_BAD_ANY_CAST _LIBCPP_AVAILABILITY_HAS_BAD_OPTIONAL_ACCESS # define _LIBCPP_AVAILABILITY_HAS_BAD_ANY_CAST _LIBCPP_AVAILABILITY_HAS_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((availability(watchos,strict,introduced=5.0))) # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((availability(watchos, strict, introduced = 5.0)))
# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS # define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS # define _LIBCPP_AVAILABILITY_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
@ -175,11 +172,11 @@
# else # else
# define _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY 1 # define _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY 1
# endif # endif
# define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY \ # define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY \
__attribute__((availability(macos,strict,introduced=10.15))) \ __attribute__((availability(macos, strict, introduced = 10.15))) \
__attribute__((availability(ios,strict,introduced=13.0))) \ __attribute__((availability(ios, strict, introduced = 13.0))) \
__attribute__((availability(tvos,strict,introduced=13.0))) \ __attribute__((availability(tvos, strict, introduced = 13.0))) \
__attribute__((availability(watchos,strict,introduced=6.0))) __attribute__((availability(watchos, strict, introduced = 6.0)))
// clang-format off // clang-format off
# define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH \ # define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH \
_Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \ _Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \
@ -204,13 +201,13 @@
# else # else
# define _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT 1 # define _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT 1
# endif # endif
# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT \ # define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT \
__attribute__((availability(macos,strict,introduced=13.3))) \ __attribute__((availability(macos, strict, introduced = 13.3))) \
__attribute__((availability(ios,strict,introduced=16.3))) \ __attribute__((availability(ios, strict, introduced = 16.3))) \
__attribute__((availability(tvos,strict,introduced=16.3))) \ __attribute__((availability(tvos, strict, introduced = 16.3))) \
__attribute__((availability(watchos,strict,introduced=9.3))) __attribute__((availability(watchos, strict, introduced = 9.3)))
// c++20 synchronization library // c++20 synchronization library
// clang-format off // clang-format off
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) || \ # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) || \
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \ (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \
@ -220,19 +217,18 @@
# define _LIBCPP_AVAILABILITY_HAS_SYNC 0 # define _LIBCPP_AVAILABILITY_HAS_SYNC 0
# else # else
# define _LIBCPP_AVAILABILITY_HAS_SYNC 1 # define _LIBCPP_AVAILABILITY_HAS_SYNC 1
# endif # endif
# define _LIBCPP_AVAILABILITY_SYNC \ # define _LIBCPP_AVAILABILITY_SYNC \
__attribute__((availability(macos,strict,introduced=11.0))) \ __attribute__((availability(macos, strict, introduced = 11.0))) \
__attribute__((availability(ios,strict,introduced=14.0))) \ __attribute__((availability(ios, strict, introduced = 14.0))) \
__attribute__((availability(tvos,strict,introduced=14.0))) \ __attribute__((availability(tvos, strict, introduced = 14.0))) \
__attribute__((availability(watchos,strict,introduced=7.0))) __attribute__((availability(watchos, strict, introduced = 7.0)))
// __libcpp_verbose_abort // __libcpp_verbose_abort
// TODO: Update once this is released // TODO: Update once this is released
# define _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT 0 # define _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT 0
# define _LIBCPP_AVAILABILITY_VERBOSE_ABORT \ # define _LIBCPP_AVAILABILITY_VERBOSE_ABORT __attribute__((unavailable))
__attribute__((unavailable))
// std::pmr // std::pmr
// clang-format off // clang-format off
@ -276,7 +272,8 @@
// ...New vendors can add availability markup here... // ...New vendors can add availability markup here...
# error "It looks like you're trying to enable vendor availability markup, but you haven't defined the corresponding macros yet!" # error \
"It looks like you're trying to enable vendor availability markup, but you haven't defined the corresponding macros yet!"
#endif #endif
@ -284,13 +281,13 @@
// Those are defined in terms of the availability attributes above, and // Those are defined in terms of the availability attributes above, and
// should not be vendor-specific. // should not be vendor-specific.
#if defined(_LIBCPP_HAS_NO_EXCEPTIONS) #if defined(_LIBCPP_HAS_NO_EXCEPTIONS)
# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST # define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS # define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS # define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
#else #else
# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST # define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST
# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS # define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS # define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
#endif #endif
#endif // _LIBCPP___AVAILABILITY #endif // _LIBCPP___AVAILABILITY

View File

@ -22,8 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20 #if _LIBCPP_STD_VER >= 20
template <class _ToType, class _FromType> template <class _ToType, class _FromType>
requires(sizeof(_ToType) == sizeof(_FromType) && requires(sizeof(_ToType) == sizeof(_FromType) && is_trivially_copyable_v<_ToType> &&
is_trivially_copyable_v<_ToType> &&
is_trivially_copyable_v<_FromType>) is_trivially_copyable_v<_FromType>)
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _FromType& __from) noexcept { _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _FromType& __from) noexcept {
return __builtin_bit_cast(_ToType, __from); return __builtin_bit_cast(_ToType, __from);

View File

@ -33,7 +33,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_ceil(_Tp __t) no
if constexpr (sizeof(_Tp) >= sizeof(unsigned)) if constexpr (sizeof(_Tp) >= sizeof(unsigned))
return _Tp{1} << __n; return _Tp{1} << __n;
else { else {
const unsigned __extra = numeric_limits<unsigned>::digits - numeric_limits<_Tp>::digits; const unsigned __extra = numeric_limits<unsigned>::digits - numeric_limits<_Tp>::digits;
const unsigned __ret_val = 1u << (__n + __extra); const unsigned __ret_val = 1u << (__n + __extra);
return (_Tp)(__ret_val >> __extra); return (_Tp)(__ret_val >> __extra);
} }

Some files were not shown because too many files have changed in this diff Show More