mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-26 13:01:34 +03:00
libcxx: update to LLVM 22
This commit is contained in:
+11
-5
@@ -10,24 +10,28 @@
|
|||||||
#ifndef _LIBCPP___ALGORITHM_ALL_OF_H
|
#ifndef _LIBCPP___ALGORITHM_ALL_OF_H
|
||||||
#define _LIBCPP___ALGORITHM_ALL_OF_H
|
#define _LIBCPP___ALGORITHM_ALL_OF_H
|
||||||
|
|
||||||
|
#include <__algorithm/any_of.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__functional/identity.h>
|
#include <__functional/identity.h>
|
||||||
#include <__type_traits/invoke.h>
|
#include <__type_traits/invoke.h>
|
||||||
|
#include <__utility/forward.h>
|
||||||
|
#include <__utility/move.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
_LIBCPP_PUSH_MACROS
|
||||||
|
#include <__undef_macros>
|
||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
template <class _Iter, class _Sent, class _Proj, class _Pred>
|
template <class _Iter, class _Sent, class _Proj, class _Pred>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
|
||||||
__all_of(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
|
__all_of(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
|
||||||
for (; __first != __last; ++__first) {
|
using _Ref = decltype(std::__invoke(__proj, *__first));
|
||||||
if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
|
auto __negated_pred = [&__pred](_Ref __arg) -> bool { return !std::__invoke(__pred, std::forward<_Ref>(__arg)); };
|
||||||
return false;
|
return !std::__any_of(std::move(__first), std::move(__last), __negated_pred, __proj);
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _InputIterator, class _Predicate>
|
template <class _InputIterator, class _Predicate>
|
||||||
@@ -39,4 +43,6 @@ all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
|||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
|
_LIBCPP_POP_MACROS
|
||||||
|
|
||||||
#endif // _LIBCPP___ALGORITHM_ALL_OF_H
|
#endif // _LIBCPP___ALGORITHM_ALL_OF_H
|
||||||
|
|||||||
+4
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__type_traits/desugars_to.h>
|
#include <__type_traits/desugars_to.h>
|
||||||
|
#include <__type_traits/is_generic_transparent_comparator.h>
|
||||||
#include <__type_traits/is_integral.h>
|
#include <__type_traits/is_integral.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
@@ -48,6 +49,9 @@ inline const bool __desugars_to_v<__less_tag, __less<>, _Tp, _Tp> = true;
|
|||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
inline const bool __desugars_to_v<__totally_ordered_less_tag, __less<>, _Tp, _Tp> = is_integral<_Tp>::value;
|
inline const bool __desugars_to_v<__totally_ordered_less_tag, __less<>, _Tp, _Tp> = is_integral<_Tp>::value;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline const bool __is_generic_transparent_comparator_v<__less<> > = true;
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
#endif // _LIBCPP___ALGORITHM_COMP_H
|
#endif // _LIBCPP___ALGORITHM_COMP_H
|
||||||
|
|||||||
+28
-147
@@ -12,11 +12,10 @@
|
|||||||
#include <__algorithm/copy_move_common.h>
|
#include <__algorithm/copy_move_common.h>
|
||||||
#include <__algorithm/for_each_segment.h>
|
#include <__algorithm/for_each_segment.h>
|
||||||
#include <__algorithm/min.h>
|
#include <__algorithm/min.h>
|
||||||
|
#include <__algorithm/specialized_algorithms.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__fwd/bit_reference.h>
|
|
||||||
#include <__iterator/iterator_traits.h>
|
#include <__iterator/iterator_traits.h>
|
||||||
#include <__iterator/segmented_iterator.h>
|
#include <__iterator/segmented_iterator.h>
|
||||||
#include <__memory/pointer_traits.h>
|
|
||||||
#include <__type_traits/common_type.h>
|
#include <__type_traits/common_type.h>
|
||||||
#include <__type_traits/enable_if.h>
|
#include <__type_traits/enable_if.h>
|
||||||
#include <__utility/move.h>
|
#include <__utility/move.h>
|
||||||
@@ -38,124 +37,14 @@ copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result);
|
|||||||
template <class _InIter, class _Sent, class _OutIter>
|
template <class _InIter, class _Sent, class _OutIter>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __copy(_InIter, _Sent, _OutIter);
|
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __copy(_InIter, _Sent, _OutIter);
|
||||||
|
|
||||||
template <class _Cp, bool _IsConst>
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_aligned(
|
|
||||||
__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
|
|
||||||
using _In = __bit_iterator<_Cp, _IsConst>;
|
|
||||||
using difference_type = typename _In::difference_type;
|
|
||||||
using __storage_type = typename _In::__storage_type;
|
|
||||||
|
|
||||||
const int __bits_per_word = _In::__bits_per_word;
|
|
||||||
difference_type __n = __last - __first;
|
|
||||||
if (__n > 0) {
|
|
||||||
// do first word
|
|
||||||
if (__first.__ctz_ != 0) {
|
|
||||||
unsigned __clz = __bits_per_word - __first.__ctz_;
|
|
||||||
difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
|
|
||||||
__n -= __dn;
|
|
||||||
__storage_type __m = std::__middle_mask<__storage_type>(__clz - __dn, __first.__ctz_);
|
|
||||||
__storage_type __b = *__first.__seg_ & __m;
|
|
||||||
*__result.__seg_ &= ~__m;
|
|
||||||
*__result.__seg_ |= __b;
|
|
||||||
__result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
|
|
||||||
__result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
|
|
||||||
++__first.__seg_;
|
|
||||||
// __first.__ctz_ = 0;
|
|
||||||
}
|
|
||||||
// __first.__ctz_ == 0;
|
|
||||||
// do middle words
|
|
||||||
__storage_type __nw = __n / __bits_per_word;
|
|
||||||
std::copy(std::__to_address(__first.__seg_),
|
|
||||||
std::__to_address(__first.__seg_ + __nw),
|
|
||||||
std::__to_address(__result.__seg_));
|
|
||||||
__n -= __nw * __bits_per_word;
|
|
||||||
__result.__seg_ += __nw;
|
|
||||||
// do last word
|
|
||||||
if (__n > 0) {
|
|
||||||
__first.__seg_ += __nw;
|
|
||||||
__storage_type __m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
|
|
||||||
__storage_type __b = *__first.__seg_ & __m;
|
|
||||||
*__result.__seg_ &= ~__m;
|
|
||||||
*__result.__seg_ |= __b;
|
|
||||||
__result.__ctz_ = static_cast<unsigned>(__n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return __result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class _Cp, bool _IsConst>
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_unaligned(
|
|
||||||
__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
|
|
||||||
using _In = __bit_iterator<_Cp, _IsConst>;
|
|
||||||
using difference_type = typename _In::difference_type;
|
|
||||||
using __storage_type = typename _In::__storage_type;
|
|
||||||
|
|
||||||
const int __bits_per_word = _In::__bits_per_word;
|
|
||||||
difference_type __n = __last - __first;
|
|
||||||
if (__n > 0) {
|
|
||||||
// do first word
|
|
||||||
if (__first.__ctz_ != 0) {
|
|
||||||
unsigned __clz_f = __bits_per_word - __first.__ctz_;
|
|
||||||
difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
|
|
||||||
__n -= __dn;
|
|
||||||
__storage_type __m = std::__middle_mask<__storage_type>(__clz_f - __dn, __first.__ctz_);
|
|
||||||
__storage_type __b = *__first.__seg_ & __m;
|
|
||||||
unsigned __clz_r = __bits_per_word - __result.__ctz_;
|
|
||||||
__storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
|
|
||||||
__m = std::__middle_mask<__storage_type>(__clz_r - __ddn, __result.__ctz_);
|
|
||||||
*__result.__seg_ &= ~__m;
|
|
||||||
if (__result.__ctz_ > __first.__ctz_)
|
|
||||||
*__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
|
|
||||||
else
|
|
||||||
*__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
|
|
||||||
__result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
|
|
||||||
__result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
|
|
||||||
__dn -= __ddn;
|
|
||||||
if (__dn > 0) {
|
|
||||||
__m = std::__trailing_mask<__storage_type>(__bits_per_word - __dn);
|
|
||||||
*__result.__seg_ &= ~__m;
|
|
||||||
*__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
|
|
||||||
__result.__ctz_ = static_cast<unsigned>(__dn);
|
|
||||||
}
|
|
||||||
++__first.__seg_;
|
|
||||||
// __first.__ctz_ = 0;
|
|
||||||
}
|
|
||||||
// __first.__ctz_ == 0;
|
|
||||||
// do middle words
|
|
||||||
unsigned __clz_r = __bits_per_word - __result.__ctz_;
|
|
||||||
__storage_type __m = std::__leading_mask<__storage_type>(__result.__ctz_);
|
|
||||||
for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) {
|
|
||||||
__storage_type __b = *__first.__seg_;
|
|
||||||
*__result.__seg_ &= ~__m;
|
|
||||||
*__result.__seg_ |= __b << __result.__ctz_;
|
|
||||||
++__result.__seg_;
|
|
||||||
*__result.__seg_ &= __m;
|
|
||||||
*__result.__seg_ |= __b >> __clz_r;
|
|
||||||
}
|
|
||||||
// do last word
|
|
||||||
if (__n > 0) {
|
|
||||||
__m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
|
|
||||||
__storage_type __b = *__first.__seg_ & __m;
|
|
||||||
__storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r));
|
|
||||||
__m = std::__middle_mask<__storage_type>(__clz_r - __dn, __result.__ctz_);
|
|
||||||
*__result.__seg_ &= ~__m;
|
|
||||||
*__result.__seg_ |= __b << __result.__ctz_;
|
|
||||||
__result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
|
|
||||||
__result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
|
|
||||||
__n -= __dn;
|
|
||||||
if (__n > 0) {
|
|
||||||
__m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
|
|
||||||
*__result.__seg_ &= ~__m;
|
|
||||||
*__result.__seg_ |= __b >> __dn;
|
|
||||||
__result.__ctz_ = static_cast<unsigned>(__n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return __result;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct __copy_impl {
|
struct __copy_impl {
|
||||||
template <class _InIter, class _Sent, class _OutIter>
|
template <class _InIter,
|
||||||
|
class _Sent,
|
||||||
|
class _OutIter,
|
||||||
|
__enable_if_t<!__specialized_algorithm<_Algorithm::__copy,
|
||||||
|
__iterator_pair<_InIter, _Sent>,
|
||||||
|
__single_iterator<_OutIter> >::__has_algorithm,
|
||||||
|
int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||||
operator()(_InIter __first, _Sent __last, _OutIter __result) const {
|
operator()(_InIter __first, _Sent __last, _OutIter __result) const {
|
||||||
while (__first != __last) {
|
while (__first != __last) {
|
||||||
@@ -167,37 +56,39 @@ struct __copy_impl {
|
|||||||
return std::make_pair(std::move(__first), std::move(__result));
|
return std::make_pair(std::move(__first), std::move(__result));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _InIter, class _OutIter>
|
template <class _InIter,
|
||||||
struct _CopySegment {
|
class _Sent,
|
||||||
using _Traits _LIBCPP_NODEBUG = __segmented_iterator_traits<_InIter>;
|
class _OutIter,
|
||||||
|
__enable_if_t<__specialized_algorithm<_Algorithm::__copy,
|
||||||
|
__iterator_pair<_InIter, _Sent>,
|
||||||
|
__single_iterator<_OutIter> >::__has_algorithm,
|
||||||
|
int> = 0>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static pair<_InIter, _OutIter>
|
||||||
|
operator()(_InIter __first, _Sent __last, _OutIter __result) {
|
||||||
|
return __specialized_algorithm<_Algorithm::__copy, __iterator_pair<_InIter, _Sent>, __single_iterator<_OutIter> >()(
|
||||||
|
std::move(__first), std::move(__last), std::move(__result));
|
||||||
|
}
|
||||||
|
|
||||||
_OutIter& __result_;
|
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit _CopySegment(_OutIter& __result)
|
|
||||||
: __result_(__result) {}
|
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
|
||||||
operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
|
|
||||||
__result_ = std::__copy(__lfirst, __llast, std::move(__result_)).second;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||||
std::__for_each_segment(__first, __last, _CopySegment<_InIter, _OutIter>(__result));
|
using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
|
||||||
|
std::__for_each_segment(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
|
||||||
|
__result = std::__copy(std::move(__lfirst), std::move(__llast), std::move(__result)).second;
|
||||||
|
});
|
||||||
return std::make_pair(__last, std::move(__result));
|
return std::make_pair(__last, std::move(__result));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _InIter,
|
template <class _InIter,
|
||||||
class _OutIter,
|
class _OutIter,
|
||||||
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
||||||
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
|
!__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||||
using _Traits = __segmented_iterator_traits<_OutIter>;
|
using _Traits = __segmented_iterator_traits<_OutIter>;
|
||||||
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
|
using _DiffT =
|
||||||
|
typename common_type<__iterator_difference_type<_InIter>, __iterator_difference_type<_OutIter> >::type;
|
||||||
|
|
||||||
if (__first == __last)
|
if (__first == __last)
|
||||||
return std::make_pair(std::move(__first), std::move(__result));
|
return std::make_pair(std::move(__first), std::move(__result));
|
||||||
@@ -217,16 +108,6 @@ struct __copy_impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Cp, bool _IsConst>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<__bit_iterator<_Cp, _IsConst>, __bit_iterator<_Cp, false> >
|
|
||||||
operator()(__bit_iterator<_Cp, _IsConst> __first,
|
|
||||||
__bit_iterator<_Cp, _IsConst> __last,
|
|
||||||
__bit_iterator<_Cp, false> __result) const {
|
|
||||||
if (__first.__ctz_ == __result.__ctz_)
|
|
||||||
return std::make_pair(__last, std::__copy_aligned(__first, __last, __result));
|
|
||||||
return std::make_pair(__last, std::__copy_unaligned(__first, __last, __result));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
|
template <class _In, class _Out, __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*>
|
||||||
|
|||||||
+9
-24
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <__algorithm/copy_move_common.h>
|
#include <__algorithm/copy_move_common.h>
|
||||||
#include <__algorithm/copy_n.h>
|
#include <__algorithm/copy_n.h>
|
||||||
|
#include <__algorithm/for_each_segment.h>
|
||||||
#include <__algorithm/iterator_operations.h>
|
#include <__algorithm/iterator_operations.h>
|
||||||
#include <__algorithm/min.h>
|
#include <__algorithm/min.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
@@ -170,37 +171,20 @@ struct __copy_backward_impl {
|
|||||||
return std::make_pair(std::move(__original_last_iter), std::move(__result));
|
return std::make_pair(std::move(__original_last_iter), std::move(__result));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
|
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||||
using _Traits = __segmented_iterator_traits<_InIter>;
|
using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
|
||||||
auto __sfirst = _Traits::__segment(__first);
|
std::__for_each_segment_backward(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
|
||||||
auto __slast = _Traits::__segment(__last);
|
__result = std::__copy_backward<_AlgPolicy>(std::move(__lfirst), std::move(__llast), std::move(__result)).second;
|
||||||
if (__sfirst == __slast) {
|
});
|
||||||
auto __iters =
|
|
||||||
std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
|
|
||||||
return std::make_pair(__last, __iters.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
__result =
|
|
||||||
std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
|
|
||||||
.second;
|
|
||||||
--__slast;
|
|
||||||
while (__sfirst != __slast) {
|
|
||||||
__result =
|
|
||||||
std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
|
|
||||||
.second;
|
|
||||||
--__slast;
|
|
||||||
}
|
|
||||||
__result = std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
|
|
||||||
.second;
|
|
||||||
return std::make_pair(__last, std::move(__result));
|
return std::make_pair(__last, std::move(__result));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _InIter,
|
template <class _InIter,
|
||||||
class _OutIter,
|
class _OutIter,
|
||||||
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
||||||
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
|
!__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||||
@@ -214,7 +198,8 @@ struct __copy_backward_impl {
|
|||||||
|
|
||||||
auto __local_last = _Traits::__local(__result);
|
auto __local_last = _Traits::__local(__result);
|
||||||
while (true) {
|
while (true) {
|
||||||
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
|
using _DiffT =
|
||||||
|
typename common_type<__iterator_difference_type<_InIter>, __iterator_difference_type<_OutIter> >::type;
|
||||||
|
|
||||||
auto __local_first = _Traits::__begin(__segment_iterator);
|
auto __local_first = _Traits::__begin(__segment_iterator);
|
||||||
auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
|
auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
|
||||||
|
|||||||
+50
-16
@@ -10,31 +10,63 @@
|
|||||||
#define _LIBCPP___ALGORITHM_COPY_N_H
|
#define _LIBCPP___ALGORITHM_COPY_N_H
|
||||||
|
|
||||||
#include <__algorithm/copy.h>
|
#include <__algorithm/copy.h>
|
||||||
|
#include <__algorithm/iterator_operations.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__iterator/iterator_traits.h>
|
#include <__iterator/iterator_traits.h>
|
||||||
#include <__type_traits/enable_if.h>
|
#include <__type_traits/enable_if.h>
|
||||||
#include <__utility/convert_to_integral.h>
|
#include <__utility/convert_to_integral.h>
|
||||||
|
#include <__utility/move.h>
|
||||||
|
#include <__utility/pair.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
_LIBCPP_PUSH_MACROS
|
||||||
|
#include <__undef_macros>
|
||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
|
template <class _AlgPolicy,
|
||||||
|
class _InIter,
|
||||||
|
class _OutIter,
|
||||||
|
__enable_if_t<__has_random_access_iterator_category<_InIter>::value, int> = 0>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
|
||||||
|
__copy_n(_InIter __first, typename _IterOps<_AlgPolicy>::template __difference_type<_InIter> __n, _OutIter __result) {
|
||||||
|
return std::__copy(__first, __first + __n, std::move(__result));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _AlgPolicy,
|
||||||
|
class _InIter,
|
||||||
|
class _OutIter,
|
||||||
|
__enable_if_t<!__has_random_access_iterator_category<_InIter>::value, int> = 0>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
|
||||||
|
__copy_n(_InIter __first, typename _IterOps<_AlgPolicy>::template __difference_type<_InIter> __n, _OutIter __result) {
|
||||||
|
while (__n != 0) {
|
||||||
|
*__result = *__first;
|
||||||
|
++__first;
|
||||||
|
++__result;
|
||||||
|
--__n;
|
||||||
|
}
|
||||||
|
return std::make_pair(std::move(__first), std::move(__result));
|
||||||
|
}
|
||||||
|
|
||||||
|
// The InputIterator case is handled specially here because it's been written in a way to avoid incrementing __first
|
||||||
|
// if not absolutely required. This was done to allow its use with istream_iterator and we want to avoid breaking
|
||||||
|
// people, at least currently.
|
||||||
|
// See https://github.com/llvm/llvm-project/commit/99847d2bf132854fffa019bab19818768102ccad
|
||||||
template <class _InputIterator,
|
template <class _InputIterator,
|
||||||
class _Size,
|
class _Size,
|
||||||
class _OutputIterator,
|
class _OutputIterator,
|
||||||
__enable_if_t<__has_input_iterator_category<_InputIterator>::value &&
|
__enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
|
||||||
!__has_random_access_iterator_category<_InputIterator>::value,
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||||
int> = 0>
|
copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) {
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
using _IntegralSize = decltype(std::__convert_to_integral(__n));
|
||||||
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
|
_IntegralSize __converted = __n;
|
||||||
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
|
if (__converted > 0) {
|
||||||
_IntegralSize __n = __orig_n;
|
|
||||||
if (__n > 0) {
|
|
||||||
*__result = *__first;
|
*__result = *__first;
|
||||||
++__result;
|
++__result;
|
||||||
for (--__n; __n > 0; --__n) {
|
for (--__converted; __converted > 0; --__converted) {
|
||||||
++__first;
|
++__first;
|
||||||
*__result = *__first;
|
*__result = *__first;
|
||||||
++__result;
|
++__result;
|
||||||
@@ -46,15 +78,17 @@ copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
|
|||||||
template <class _InputIterator,
|
template <class _InputIterator,
|
||||||
class _Size,
|
class _Size,
|
||||||
class _OutputIterator,
|
class _OutputIterator,
|
||||||
__enable_if_t<__has_random_access_iterator_category<_InputIterator>::value, int> = 0>
|
__enable_if_t<!__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||||
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
|
copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) {
|
||||||
typedef typename iterator_traits<_InputIterator>::difference_type difference_type;
|
using _IntegralSize = decltype(std::__convert_to_integral(__n));
|
||||||
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
|
_IntegralSize __converted = __n;
|
||||||
_IntegralSize __n = __orig_n;
|
return std::__copy_n<_ClassicAlgPolicy>(__first, __iterator_difference_type<_InputIterator>(__converted), __result)
|
||||||
return std::copy(__first, __first + difference_type(__n), __result);
|
.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
|
_LIBCPP_POP_MACROS
|
||||||
|
|
||||||
#endif // _LIBCPP___ALGORITHM_COPY_N_H
|
#endif // _LIBCPP___ALGORITHM_COPY_N_H
|
||||||
|
|||||||
+2
-2
@@ -72,7 +72,7 @@ __count_bool(__bit_iterator<_Cp, _IsConst> __first, typename __size_difference_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class, class _Cp, bool _IsConst, class _Tp, class _Proj, __enable_if_t<__is_identity<_Proj>::value, int> = 0>
|
template <class, class _Cp, bool _IsConst, class _Tp, class _Proj, __enable_if_t<__is_identity<_Proj>::value, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<__bit_iterator<_Cp, _IsConst> >
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iterator_difference_type<__bit_iterator<_Cp, _IsConst> >
|
||||||
__count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value, _Proj&) {
|
__count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value, _Proj&) {
|
||||||
if (__value)
|
if (__value)
|
||||||
return std::__count_bool<true>(
|
return std::__count_bool<true>(
|
||||||
@@ -82,7 +82,7 @@ __count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __l
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class _InputIterator, class _Tp>
|
template <class _InputIterator, class _Tp>
|
||||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<_InputIterator>
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iterator_difference_type<_InputIterator>
|
||||||
count(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
|
count(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
|
||||||
__identity __proj;
|
__identity __proj;
|
||||||
return std::__count<_ClassicAlgPolicy>(__first, __last, __value, __proj);
|
return std::__count<_ClassicAlgPolicy>(__first, __last, __value, __proj);
|
||||||
|
|||||||
+43
-55
@@ -160,22 +160,28 @@ template <class _Cp,
|
|||||||
bool _IsConst1,
|
bool _IsConst1,
|
||||||
bool _IsConst2,
|
bool _IsConst2,
|
||||||
class _BinaryPredicate,
|
class _BinaryPredicate,
|
||||||
__enable_if_t<__desugars_to_v<__equal_tag, _BinaryPredicate, bool, bool>, int> = 0>
|
class _Proj1,
|
||||||
|
class _Proj2,
|
||||||
|
__enable_if_t<__is_identity<_Proj1>::value && __is_identity<_Proj2>::value &&
|
||||||
|
__desugars_to_v<__equal_tag, _BinaryPredicate, bool, bool>,
|
||||||
|
int> = 0>
|
||||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(
|
||||||
__bit_iterator<_Cp, _IsConst1> __first1,
|
__bit_iterator<_Cp, _IsConst1> __first1,
|
||||||
__bit_iterator<_Cp, _IsConst1> __last1,
|
__bit_iterator<_Cp, _IsConst1> __last1,
|
||||||
__bit_iterator<_Cp, _IsConst2> __first2,
|
__bit_iterator<_Cp, _IsConst2> __first2,
|
||||||
_BinaryPredicate) {
|
_BinaryPredicate,
|
||||||
|
_Proj1&,
|
||||||
|
_Proj2&) {
|
||||||
if (__first1.__ctz_ == __first2.__ctz_)
|
if (__first1.__ctz_ == __first2.__ctz_)
|
||||||
return std::__equal_aligned(__first1, __last1, __first2);
|
return std::__equal_aligned(__first1, __last1, __first2);
|
||||||
return std::__equal_unaligned(__first1, __last1, __first2);
|
return std::__equal_unaligned(__first1, __last1, __first2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
template <class _InIter1, class _Sent1, class _InIter2, class _Pred, class _Proj1, class _Proj2>
|
||||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(
|
||||||
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate& __pred) {
|
_InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
|
||||||
for (; __first1 != __last1; ++__first1, (void)++__first2)
|
for (; __first1 != __last1; ++__first1, (void)++__first2)
|
||||||
if (!__pred(*__first1, *__first2))
|
if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -183,19 +189,23 @@ template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
|||||||
template <class _Tp,
|
template <class _Tp,
|
||||||
class _Up,
|
class _Up,
|
||||||
class _BinaryPredicate,
|
class _BinaryPredicate,
|
||||||
__enable_if_t<__desugars_to_v<__equal_tag, _BinaryPredicate, _Tp, _Up> && !is_volatile<_Tp>::value &&
|
class _Proj1,
|
||||||
!is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
|
class _Proj2,
|
||||||
|
__enable_if_t<__is_identity<_Proj1>::value && __is_identity<_Proj2>::value &&
|
||||||
|
__desugars_to_v<__equal_tag, _BinaryPredicate, _Tp, _Up> && !is_volatile<_Tp>::value &&
|
||||||
|
!is_volatile<_Up>::value && __is_trivially_equality_comparable_v<_Tp, _Up>,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||||
__equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) {
|
__equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&, _Proj1&, _Proj2&) {
|
||||||
return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
|
return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
||||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||||
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
|
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
|
||||||
|
__identity __proj;
|
||||||
return std::__equal_iter_impl(
|
return std::__equal_iter_impl(
|
||||||
std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred);
|
std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred, __proj, __proj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _InputIterator1, class _InputIterator2>
|
template <class _InputIterator1, class _InputIterator2>
|
||||||
@@ -206,52 +216,28 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first
|
|||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 14
|
#if _LIBCPP_STD_VER >= 14
|
||||||
|
|
||||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
|
template <bool __known_equal_length,
|
||||||
|
class _Iter1,
|
||||||
|
class _Sent1,
|
||||||
|
class _Iter2,
|
||||||
|
class _Sent2,
|
||||||
|
class _Pred,
|
||||||
|
class _Proj1,
|
||||||
|
class _Proj2>
|
||||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
|
||||||
_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __comp, _Proj1& __proj1, _Proj2& __proj2) {
|
_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __comp, _Proj1& __proj1, _Proj2& __proj2) {
|
||||||
while (__first1 != __last1 && __first2 != __last2) {
|
if constexpr (__known_equal_length) {
|
||||||
if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
|
return std::__equal_iter_impl(
|
||||||
return false;
|
std::move(__first1), std::move(__last1), std::move(__first2), __comp, __proj1, __proj2);
|
||||||
++__first1;
|
} else {
|
||||||
++__first2;
|
while (__first1 != __last1 && __first2 != __last2) {
|
||||||
|
if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
|
||||||
|
return false;
|
||||||
|
++__first1;
|
||||||
|
++__first2;
|
||||||
|
}
|
||||||
|
return __first1 == __last1 && __first2 == __last2;
|
||||||
}
|
}
|
||||||
return __first1 == __last1 && __first2 == __last2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class _Tp,
|
|
||||||
class _Up,
|
|
||||||
class _Pred,
|
|
||||||
class _Proj1,
|
|
||||||
class _Proj2,
|
|
||||||
__enable_if_t<__desugars_to_v<__equal_tag, _Pred, _Tp, _Up> && __is_identity<_Proj1>::value &&
|
|
||||||
__is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value &&
|
|
||||||
__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
|
|
||||||
int> = 0>
|
|
||||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
|
||||||
__equal_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) {
|
|
||||||
return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class _Cp,
|
|
||||||
bool _IsConst1,
|
|
||||||
bool _IsConst2,
|
|
||||||
class _Pred,
|
|
||||||
class _Proj1,
|
|
||||||
class _Proj2,
|
|
||||||
__enable_if_t<__desugars_to_v<__equal_tag, _Pred, bool, bool> && __is_identity<_Proj1>::value &&
|
|
||||||
__is_identity<_Proj2>::value,
|
|
||||||
int> = 0>
|
|
||||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
|
|
||||||
__bit_iterator<_Cp, _IsConst1> __first1,
|
|
||||||
__bit_iterator<_Cp, _IsConst1> __last1,
|
|
||||||
__bit_iterator<_Cp, _IsConst2> __first2,
|
|
||||||
__bit_iterator<_Cp, _IsConst2>,
|
|
||||||
_Pred&,
|
|
||||||
_Proj1&,
|
|
||||||
_Proj2&) {
|
|
||||||
if (__first1.__ctz_ == __first2.__ctz_)
|
|
||||||
return std::__equal_aligned(__first1, __last1, __first2);
|
|
||||||
return std::__equal_unaligned(__first1, __last1, __first2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
||||||
@@ -261,13 +247,15 @@ equal(_InputIterator1 __first1,
|
|||||||
_InputIterator2 __first2,
|
_InputIterator2 __first2,
|
||||||
_InputIterator2 __last2,
|
_InputIterator2 __last2,
|
||||||
_BinaryPredicate __pred) {
|
_BinaryPredicate __pred) {
|
||||||
if constexpr (__has_random_access_iterator_category<_InputIterator1>::value &&
|
static constexpr bool __both_random_access =
|
||||||
__has_random_access_iterator_category<_InputIterator2>::value) {
|
__has_random_access_iterator_category<_InputIterator1>::value &&
|
||||||
|
__has_random_access_iterator_category<_InputIterator2>::value;
|
||||||
|
if constexpr (__both_random_access) {
|
||||||
if (std::distance(__first1, __last1) != std::distance(__first2, __last2))
|
if (std::distance(__first1, __last1) != std::distance(__first2, __last2))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
__identity __proj;
|
__identity __proj;
|
||||||
return std::__equal_impl(
|
return std::__equal_impl<__both_random_access>(
|
||||||
std::__unwrap_iter(__first1),
|
std::__unwrap_iter(__first1),
|
||||||
std::__unwrap_iter(__last1),
|
std::__unwrap_iter(__last1),
|
||||||
std::__unwrap_iter(__first2),
|
std::__unwrap_iter(__first2),
|
||||||
|
|||||||
+26
-8
@@ -10,8 +10,12 @@
|
|||||||
#define _LIBCPP___ALGORITHM_FILL_H
|
#define _LIBCPP___ALGORITHM_FILL_H
|
||||||
|
|
||||||
#include <__algorithm/fill_n.h>
|
#include <__algorithm/fill_n.h>
|
||||||
|
#include <__algorithm/for_each_segment.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__iterator/iterator_traits.h>
|
#include <__iterator/iterator_traits.h>
|
||||||
|
#include <__iterator/segmented_iterator.h>
|
||||||
|
#include <__type_traits/enable_if.h>
|
||||||
|
#include <__type_traits/is_same.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
@@ -21,23 +25,37 @@ _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 _Sentinel, class _Tp>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||||
__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, forward_iterator_tag) {
|
__fill(_ForwardIterator __first, _Sentinel __last, const _Tp& __value) {
|
||||||
|
#ifndef _LIBCPP_CXX03_LANG
|
||||||
|
if constexpr (is_same<_ForwardIterator, _Sentinel>::value && __is_segmented_iterator_v<_ForwardIterator>) {
|
||||||
|
using __local_iterator_t = typename __segmented_iterator_traits<_ForwardIterator>::__local_iterator;
|
||||||
|
std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
|
||||||
|
std::__fill(__lfirst, __llast, __value);
|
||||||
|
});
|
||||||
|
return __last;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
for (; __first != __last; ++__first)
|
for (; __first != __last; ++__first)
|
||||||
*__first = __value;
|
*__first = __value;
|
||||||
|
return __first;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _RandomAccessIterator, class _Tp>
|
template <class _RandomAccessIterator,
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
class _Tp,
|
||||||
__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, random_access_iterator_tag) {
|
__enable_if_t<__has_random_access_iterator_category<_RandomAccessIterator>::value &&
|
||||||
std::fill_n(__first, __last - __first, __value);
|
!__is_segmented_iterator_v<_RandomAccessIterator>,
|
||||||
|
int> = 0>
|
||||||
|
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
|
||||||
|
__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value) {
|
||||||
|
return 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 void
|
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|||||||
+32
-46
@@ -9,11 +9,14 @@
|
|||||||
#ifndef _LIBCPP___ALGORITHM_FILL_N_H
|
#ifndef _LIBCPP___ALGORITHM_FILL_N_H
|
||||||
#define _LIBCPP___ALGORITHM_FILL_N_H
|
#define _LIBCPP___ALGORITHM_FILL_N_H
|
||||||
|
|
||||||
#include <__algorithm/min.h>
|
#include <__algorithm/for_each_n_segment.h>
|
||||||
|
#include <__algorithm/specialized_algorithms.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__fwd/bit_reference.h>
|
#include <__iterator/iterator_traits.h>
|
||||||
#include <__memory/pointer_traits.h>
|
#include <__iterator/segmented_iterator.h>
|
||||||
|
#include <__type_traits/enable_if.h>
|
||||||
#include <__utility/convert_to_integral.h>
|
#include <__utility/convert_to_integral.h>
|
||||||
|
#include <__utility/move.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
@@ -26,56 +29,39 @@ _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 <
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
class _OutputIterator,
|
||||||
__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value);
|
class _Size,
|
||||||
|
class _Tp,
|
||||||
template <bool _FillVal, class _Cp>
|
__enable_if_t<!__specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutputIterator> >::__has_algorithm,
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
|
int> = 0>
|
||||||
__fill_n_bool(__bit_iterator<_Cp, false> __first, typename __size_difference_type_traits<_Cp>::size_type __n) {
|
|
||||||
using _It = __bit_iterator<_Cp, false>;
|
|
||||||
using __storage_type = typename _It::__storage_type;
|
|
||||||
|
|
||||||
const int __bits_per_word = _It::__bits_per_word;
|
|
||||||
// do first partial word
|
|
||||||
if (__first.__ctz_ != 0) {
|
|
||||||
__storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
|
|
||||||
__storage_type __dn = std::min(__clz_f, __n);
|
|
||||||
std::__fill_masked_range(std::__to_address(__first.__seg_), __clz_f - __dn, __first.__ctz_, _FillVal);
|
|
||||||
__n -= __dn;
|
|
||||||
++__first.__seg_;
|
|
||||||
}
|
|
||||||
// do middle whole words
|
|
||||||
__storage_type __nw = __n / __bits_per_word;
|
|
||||||
std::__fill_n(std::__to_address(__first.__seg_), __nw, _FillVal ? static_cast<__storage_type>(-1) : 0);
|
|
||||||
__n -= __nw * __bits_per_word;
|
|
||||||
// do last partial word
|
|
||||||
if (__n > 0) {
|
|
||||||
__first.__seg_ += __nw;
|
|
||||||
std::__fill_masked_range(std::__to_address(__first.__seg_), __bits_per_word - __n, 0u, _FillVal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class _Cp, class _Size>
|
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false>
|
|
||||||
__fill_n(__bit_iterator<_Cp, false> __first, _Size __n, const bool& __value) {
|
|
||||||
if (__n > 0) {
|
|
||||||
if (__value)
|
|
||||||
std::__fill_n_bool<true>(__first, __n);
|
|
||||||
else
|
|
||||||
std::__fill_n_bool<false>(__first, __n);
|
|
||||||
}
|
|
||||||
return __first + __n;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class _OutputIterator, class _Size, class _Tp>
|
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||||
__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
|
__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
|
||||||
|
#ifndef _LIBCPP_CXX03_LANG
|
||||||
|
if constexpr (__is_segmented_iterator_v<_OutputIterator>) {
|
||||||
|
using __local_iterator = typename __segmented_iterator_traits<_OutputIterator>::__local_iterator;
|
||||||
|
if constexpr (__has_random_access_iterator_category<__local_iterator>::value) {
|
||||||
|
return std::__for_each_n_segment(__first, __n, [&](__local_iterator __lfirst, __local_iterator __llast) {
|
||||||
|
std::__fill_n(__lfirst, __llast - __lfirst, __value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
for (; __n > 0; ++__first, (void)--__n)
|
for (; __n > 0; ++__first, (void)--__n)
|
||||||
*__first = __value;
|
*__first = __value;
|
||||||
return __first;
|
return __first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class _OutIter,
|
||||||
|
class _Size,
|
||||||
|
class _Tp,
|
||||||
|
__enable_if_t<__specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutIter> >::__has_algorithm,
|
||||||
|
int> = 0>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutIter __fill_n(_OutIter __first, _Size __n, const _Tp& __value) {
|
||||||
|
return __specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutIter> >()(
|
||||||
|
std::move(__first), __n, __value);
|
||||||
|
}
|
||||||
|
|
||||||
template <class _OutputIterator, class _Size, class _Tp>
|
template <class _OutputIterator, class _Size, class _Tp>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||||
fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
|
fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
|
||||||
|
|||||||
+97
-40
@@ -12,16 +12,19 @@
|
|||||||
|
|
||||||
#include <__algorithm/find_segment_if.h>
|
#include <__algorithm/find_segment_if.h>
|
||||||
#include <__algorithm/min.h>
|
#include <__algorithm/min.h>
|
||||||
|
#include <__algorithm/simd_utils.h>
|
||||||
#include <__algorithm/unwrap_iter.h>
|
#include <__algorithm/unwrap_iter.h>
|
||||||
#include <__bit/countr.h>
|
#include <__bit/countr.h>
|
||||||
#include <__bit/invert_if.h>
|
#include <__bit/invert_if.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__cstddef/size_t.h>
|
||||||
#include <__functional/identity.h>
|
#include <__functional/identity.h>
|
||||||
#include <__fwd/bit_reference.h>
|
#include <__fwd/bit_reference.h>
|
||||||
#include <__iterator/segmented_iterator.h>
|
#include <__iterator/segmented_iterator.h>
|
||||||
#include <__string/constexpr_c_functions.h>
|
#include <__string/constexpr_c_functions.h>
|
||||||
#include <__type_traits/enable_if.h>
|
#include <__type_traits/enable_if.h>
|
||||||
#include <__type_traits/invoke.h>
|
#include <__type_traits/invoke.h>
|
||||||
|
#include <__type_traits/is_constant_evaluated.h>
|
||||||
#include <__type_traits/is_equality_comparable.h>
|
#include <__type_traits/is_equality_comparable.h>
|
||||||
#include <__type_traits/is_integral.h>
|
#include <__type_traits/is_integral.h>
|
||||||
#include <__type_traits/is_signed.h>
|
#include <__type_traits/is_signed.h>
|
||||||
@@ -44,46 +47,108 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
// generic implementation
|
// generic implementation
|
||||||
template <class _Iter, class _Sent, class _Tp, class _Proj>
|
template <class _Iter, class _Sent, class _Tp, class _Proj>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
|
||||||
__find(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
|
__find_loop(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
|
||||||
for (; __first != __last; ++__first)
|
for (; __first != __last; ++__first)
|
||||||
if (std::__invoke(__proj, *__first) == __value)
|
if (std::__invoke(__proj, *__first) == __value)
|
||||||
break;
|
break;
|
||||||
return __first;
|
return __first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class _Iter, class _Sent, class _Tp, class _Proj>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
|
||||||
|
__find(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
|
||||||
|
return std::__find_loop(std::move(__first), std::move(__last), __value, __proj);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if _LIBCPP_VECTORIZE_ALGORITHMS
|
||||||
|
template <class _Tp, class _Up>
|
||||||
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
|
||||||
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find_vectorized(_Tp* __first, _Tp* __last, _Up __value) {
|
||||||
|
if (!__libcpp_is_constant_evaluated()) {
|
||||||
|
constexpr size_t __unroll_count = 4;
|
||||||
|
constexpr size_t __vec_size = __native_vector_size<_Tp>;
|
||||||
|
using __vec = __simd_vector<_Tp, __vec_size>;
|
||||||
|
|
||||||
|
auto __orig_first = __first;
|
||||||
|
|
||||||
|
auto __values = static_cast<__simd_vector<_Tp, __vec_size>>(__value); // broadcast the value
|
||||||
|
while (static_cast<size_t>(__last - __first) >= __unroll_count * __vec_size) [[__unlikely__]] {
|
||||||
|
__vec __lhs[__unroll_count];
|
||||||
|
|
||||||
|
for (size_t __i = 0; __i != __unroll_count; ++__i)
|
||||||
|
__lhs[__i] = std::__load_vector<__vec>(__first + __i * __vec_size);
|
||||||
|
|
||||||
|
for (size_t __i = 0; __i != __unroll_count; ++__i) {
|
||||||
|
if (auto __cmp_res = __lhs[__i] == __values; std::__any_of(__cmp_res)) {
|
||||||
|
auto __offset = __i * __vec_size + std::__find_first_set(__cmp_res);
|
||||||
|
return __first + __offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__first += __unroll_count * __vec_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the remaining 0-3 vectors
|
||||||
|
while (static_cast<size_t>(__last - __first) >= __vec_size) {
|
||||||
|
if (auto __cmp_res = std::__load_vector<__vec>(__first) == __values; std::__any_of(__cmp_res)) {
|
||||||
|
return __first + std::__find_first_set(__cmp_res);
|
||||||
|
}
|
||||||
|
__first += __vec_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__last - __first == 0)
|
||||||
|
return __first;
|
||||||
|
|
||||||
|
// Check if we can load elements in front of the current pointer. If that's the case load a vector at
|
||||||
|
// (last - vector_size) to check the remaining elements
|
||||||
|
if (static_cast<size_t>(__first - __orig_first) >= __vec_size) {
|
||||||
|
__first = __last - __vec_size;
|
||||||
|
return __first + std::__find_first_set(std::__load_vector<__vec>(__first) == __values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__identity __proj;
|
||||||
|
return std::__find_loop(__first, __last, __value, __proj);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _LIBCPP_CXX03_LANG
|
||||||
// trivially equality comparable implementations
|
// trivially equality comparable implementations
|
||||||
template <class _Tp,
|
template <class _Tp,
|
||||||
class _Up,
|
class _Up,
|
||||||
class _Proj,
|
class _Proj,
|
||||||
__enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
|
__enable_if_t<__is_identity<_Proj>::value && __is_trivially_equality_comparable_v<_Tp, _Up>, int> = 0>
|
||||||
sizeof(_Tp) == 1,
|
|
||||||
int> = 0>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
|
||||||
if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first))
|
if constexpr (sizeof(_Tp) == 1) {
|
||||||
return __ret;
|
if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first))
|
||||||
return __last;
|
return __ret;
|
||||||
|
return __last;
|
||||||
|
}
|
||||||
|
# if _LIBCPP_HAS_WIDE_CHARACTERS
|
||||||
|
else if constexpr (sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t)) {
|
||||||
|
if (auto __ret = std::__constexpr_wmemchr(__first, __value, __last - __first))
|
||||||
|
return __ret;
|
||||||
|
return __last;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
# if _LIBCPP_VECTORIZE_ALGORITHMS
|
||||||
|
else if constexpr (is_integral<_Tp>::value) {
|
||||||
|
return std::__find_vectorized(__first, __last, __value);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
else {
|
||||||
|
__identity __proj;
|
||||||
|
return std::__find_loop(__first, __last, __value, __proj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#if _LIBCPP_HAS_WIDE_CHARACTERS
|
|
||||||
template <class _Tp,
|
|
||||||
class _Up,
|
|
||||||
class _Proj,
|
|
||||||
__enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
|
|
||||||
sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t),
|
|
||||||
int> = 0>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
|
|
||||||
if (auto __ret = std::__constexpr_wmemchr(__first, __value, __last - __first))
|
|
||||||
return __ret;
|
|
||||||
return __last;
|
|
||||||
}
|
|
||||||
#endif // _LIBCPP_HAS_WIDE_CHARACTERS
|
|
||||||
|
|
||||||
// TODO: This should also be possible to get right with different signedness
|
// TODO: This should also be possible to get right with different signedness
|
||||||
// cast integral types to allow vectorization
|
// cast integral types to allow vectorization
|
||||||
template <class _Tp,
|
template <class _Tp,
|
||||||
class _Up,
|
class _Up,
|
||||||
class _Proj,
|
class _Proj,
|
||||||
__enable_if_t<__is_identity<_Proj>::value && !__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
|
__enable_if_t<__is_identity<_Proj>::value && !__is_trivially_equality_comparable_v<_Tp, _Up> &&
|
||||||
is_integral<_Tp>::value && is_integral<_Up>::value &&
|
is_integral<_Tp>::value && is_integral<_Up>::value &&
|
||||||
is_signed<_Tp>::value == is_signed<_Up>::value,
|
is_signed<_Tp>::value == is_signed<_Up>::value,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
@@ -143,31 +208,23 @@ __find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __la
|
|||||||
|
|
||||||
// segmented iterator implementation
|
// segmented iterator implementation
|
||||||
|
|
||||||
template <class>
|
|
||||||
struct __find_segment;
|
|
||||||
|
|
||||||
template <class _SegmentedIterator,
|
template <class _SegmentedIterator,
|
||||||
class _Tp,
|
class _Tp,
|
||||||
class _Proj,
|
class _Proj,
|
||||||
__enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
|
__enable_if_t<__is_segmented_iterator_v<_SegmentedIterator>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator
|
||||||
__find(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value, _Proj& __proj) {
|
__find(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value, _Proj& __proj) {
|
||||||
return std::__find_segment_if(std::move(__first), std::move(__last), __find_segment<_Tp>(__value), __proj);
|
using __local_iterator = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator;
|
||||||
|
return std::__find_segment_if(
|
||||||
|
std::move(__first),
|
||||||
|
std::move(__last),
|
||||||
|
[&__value](__local_iterator __lfirst, __local_iterator __llast, _Proj& __lproj) {
|
||||||
|
return std::__rewrap_iter(
|
||||||
|
__lfirst, std::__find(std::__unwrap_iter(__lfirst), std::__unwrap_iter(__llast), __value, __lproj));
|
||||||
|
},
|
||||||
|
__proj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp>
|
|
||||||
struct __find_segment {
|
|
||||||
const _Tp& __value_;
|
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __find_segment(const _Tp& __value) : __value_(__value) {}
|
|
||||||
|
|
||||||
template <class _InputIterator, class _Proj>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _InputIterator
|
|
||||||
operator()(_InputIterator __first, _InputIterator __last, _Proj& __proj) const {
|
|
||||||
return std::__find(__first, __last, __value_, __proj);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// public API
|
// public API
|
||||||
template <class _InputIterator, class _Tp>
|
template <class _InputIterator, class _Tp>
|
||||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
|
||||||
|
|||||||
+105
@@ -76,6 +76,111 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class _AlgPolicy,
|
||||||
|
class _Pred,
|
||||||
|
class _Iter1,
|
||||||
|
class _Sent1,
|
||||||
|
class _Iter2,
|
||||||
|
class _Sent2,
|
||||||
|
class _Proj1,
|
||||||
|
class _Proj2>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter1> __find_end_impl(
|
||||||
|
_Iter1 __first1,
|
||||||
|
_Sent1 __sent1,
|
||||||
|
_Iter2 __first2,
|
||||||
|
_Sent2 __sent2,
|
||||||
|
_Pred& __pred,
|
||||||
|
_Proj1& __proj1,
|
||||||
|
_Proj2& __proj2,
|
||||||
|
bidirectional_iterator_tag,
|
||||||
|
bidirectional_iterator_tag) {
|
||||||
|
auto __last1 = _IterOps<_AlgPolicy>::next(__first1, __sent1);
|
||||||
|
auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __sent2);
|
||||||
|
// modeled after search algorithm (in reverse)
|
||||||
|
if (__first2 == __last2)
|
||||||
|
return std::make_pair(__last1, __last1); // Everything matches an empty sequence
|
||||||
|
_Iter1 __l1 = __last1;
|
||||||
|
_Iter2 __l2 = __last2;
|
||||||
|
--__l2;
|
||||||
|
while (true) {
|
||||||
|
// Find last element in sequence 1 that matches *(__last2-1), with a mininum of loop checks
|
||||||
|
while (true) {
|
||||||
|
if (__first1 == __l1) // return __last1 if no element matches *__first2
|
||||||
|
return std::make_pair(__last1, __last1);
|
||||||
|
if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// *__l1 matches *__l2, now match elements before here
|
||||||
|
_Iter1 __match_last = __l1;
|
||||||
|
_Iter1 __m1 = __l1;
|
||||||
|
_Iter2 __m2 = __l2;
|
||||||
|
while (true) {
|
||||||
|
if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern)
|
||||||
|
return std::make_pair(__m1, ++__match_last);
|
||||||
|
if (__m1 == __first1) // Otherwise if source exhaused, pattern not found
|
||||||
|
return std::make_pair(__last1, __last1);
|
||||||
|
|
||||||
|
// if there is a mismatch, restart with a new __l1
|
||||||
|
if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) {
|
||||||
|
break;
|
||||||
|
} // else there is a match, check next elements
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _AlgPolicy,
|
||||||
|
class _Pred,
|
||||||
|
class _Iter1,
|
||||||
|
class _Sent1,
|
||||||
|
class _Iter2,
|
||||||
|
class _Sent2,
|
||||||
|
class _Proj1,
|
||||||
|
class _Proj2>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __find_end_impl(
|
||||||
|
_Iter1 __first1,
|
||||||
|
_Sent1 __sent1,
|
||||||
|
_Iter2 __first2,
|
||||||
|
_Sent2 __sent2,
|
||||||
|
_Pred& __pred,
|
||||||
|
_Proj1& __proj1,
|
||||||
|
_Proj2& __proj2,
|
||||||
|
random_access_iterator_tag,
|
||||||
|
random_access_iterator_tag) {
|
||||||
|
typedef typename iterator_traits<_Iter1>::difference_type _D1;
|
||||||
|
auto __last1 = _IterOps<_AlgPolicy>::next(__first1, __sent1);
|
||||||
|
auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __sent2);
|
||||||
|
// Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
|
||||||
|
auto __len2 = __last2 - __first2;
|
||||||
|
if (__len2 == 0)
|
||||||
|
return std::make_pair(__last1, __last1);
|
||||||
|
auto __len1 = __last1 - __first1;
|
||||||
|
if (__len1 < __len2)
|
||||||
|
return std::make_pair(__last1, __last1);
|
||||||
|
const _Iter1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here
|
||||||
|
_Iter1 __l1 = __last1;
|
||||||
|
_Iter2 __l2 = __last2;
|
||||||
|
--__l2;
|
||||||
|
while (true) {
|
||||||
|
while (true) {
|
||||||
|
if (__s == __l1)
|
||||||
|
return std::make_pair(__last1, __last1);
|
||||||
|
if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_Iter1 __last_match = __l1;
|
||||||
|
_Iter1 __m1 = __l1;
|
||||||
|
_Iter2 __m2 = __l2;
|
||||||
|
while (true) {
|
||||||
|
if (__m2 == __first2)
|
||||||
|
return std::make_pair(__m1, ++__last_match);
|
||||||
|
// no need to check range on __m1 because __s guarantees we have enough source
|
||||||
|
if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_end_classic(
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_end_classic(
|
||||||
_ForwardIterator1 __first1,
|
_ForwardIterator1 __first1,
|
||||||
|
|||||||
+18
-24
@@ -11,45 +11,41 @@
|
|||||||
#define _LIBCPP___ALGORITHM_FOR_EACH_H
|
#define _LIBCPP___ALGORITHM_FOR_EACH_H
|
||||||
|
|
||||||
#include <__algorithm/for_each_segment.h>
|
#include <__algorithm/for_each_segment.h>
|
||||||
|
#include <__algorithm/specialized_algorithms.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__functional/identity.h>
|
#include <__functional/identity.h>
|
||||||
#include <__iterator/segmented_iterator.h>
|
#include <__iterator/segmented_iterator.h>
|
||||||
#include <__type_traits/enable_if.h>
|
|
||||||
#include <__type_traits/invoke.h>
|
#include <__type_traits/invoke.h>
|
||||||
#include <__utility/move.h>
|
#include <__type_traits/is_same.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_LIBCPP_PUSH_MACROS
|
|
||||||
#include <__undef_macros>
|
|
||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
template <class _InputIterator, class _Sent, class _Func, class _Proj>
|
template <class _InputIterator, class _Sent, class _Func, class _Proj>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
|
||||||
__for_each(_InputIterator __first, _Sent __last, _Func& __f, _Proj& __proj) {
|
__for_each(_InputIterator __first, _Sent __last, _Func& __func, _Proj& __proj) {
|
||||||
|
#ifndef _LIBCPP_CXX03_LANG
|
||||||
|
if constexpr (using _SpecialAlg =
|
||||||
|
__specialized_algorithm<_Algorithm::__for_each, __iterator_pair<_InputIterator, _Sent>>;
|
||||||
|
_SpecialAlg::__has_algorithm) {
|
||||||
|
_SpecialAlg()(__first, __last, __func, __proj);
|
||||||
|
return __last;
|
||||||
|
} else if constexpr (is_same<_InputIterator, _Sent>::value && __is_segmented_iterator_v<_InputIterator>) {
|
||||||
|
using __local_iterator_t = typename __segmented_iterator_traits<_InputIterator>::__local_iterator;
|
||||||
|
std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
|
||||||
|
std::__for_each(__lfirst, __llast, __func, __proj);
|
||||||
|
});
|
||||||
|
return __last;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
for (; __first != __last; ++__first)
|
for (; __first != __last; ++__first)
|
||||||
std::__invoke(__f, std::__invoke(__proj, *__first));
|
std::__invoke(__func, std::__invoke(__proj, *__first));
|
||||||
return __first;
|
return __first;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _LIBCPP_CXX03_LANG
|
|
||||||
template <class _SegmentedIterator,
|
|
||||||
class _Func,
|
|
||||||
class _Proj,
|
|
||||||
__enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _SegmentedIterator
|
|
||||||
__for_each(_SegmentedIterator __first, _SegmentedIterator __last, _Func& __func, _Proj& __proj) {
|
|
||||||
using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator;
|
|
||||||
std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
|
|
||||||
std::__for_each(__lfirst, __llast, __func, __proj);
|
|
||||||
});
|
|
||||||
return __last;
|
|
||||||
}
|
|
||||||
#endif // !_LIBCPP_CXX03_LANG
|
|
||||||
|
|
||||||
template <class _InputIterator, class _Func>
|
template <class _InputIterator, class _Func>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Func
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Func
|
||||||
for_each(_InputIterator __first, _InputIterator __last, _Func __f) {
|
for_each(_InputIterator __first, _InputIterator __last, _Func __f) {
|
||||||
@@ -60,6 +56,4 @@ for_each(_InputIterator __first, _InputIterator __last, _Func __f) {
|
|||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
_LIBCPP_POP_MACROS
|
|
||||||
|
|
||||||
#endif // _LIBCPP___ALGORITHM_FOR_EACH_H
|
#endif // _LIBCPP___ALGORITHM_FOR_EACH_H
|
||||||
|
|||||||
+20
-47
@@ -16,10 +16,7 @@
|
|||||||
#include <__functional/identity.h>
|
#include <__functional/identity.h>
|
||||||
#include <__iterator/iterator_traits.h>
|
#include <__iterator/iterator_traits.h>
|
||||||
#include <__iterator/segmented_iterator.h>
|
#include <__iterator/segmented_iterator.h>
|
||||||
#include <__type_traits/disjunction.h>
|
|
||||||
#include <__type_traits/enable_if.h>
|
|
||||||
#include <__type_traits/invoke.h>
|
#include <__type_traits/invoke.h>
|
||||||
#include <__type_traits/negation.h>
|
|
||||||
#include <__utility/convert_to_integral.h>
|
#include <__utility/convert_to_integral.h>
|
||||||
#include <__utility/move.h>
|
#include <__utility/move.h>
|
||||||
|
|
||||||
@@ -32,57 +29,33 @@ _LIBCPP_PUSH_MACROS
|
|||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
template <class _InputIterator,
|
template <class _InputIterator, class _Size, class _Func, class _Proj>
|
||||||
class _Size,
|
|
||||||
class _Func,
|
|
||||||
class _Proj,
|
|
||||||
__enable_if_t<!__has_random_access_iterator_category<_InputIterator>::value &&
|
|
||||||
_Or< _Not<__is_segmented_iterator<_InputIterator> >,
|
|
||||||
_Not<__has_random_access_local_iterator<_InputIterator> > >::value,
|
|
||||||
int> = 0>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
|
||||||
__for_each_n(_InputIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
|
__for_each_n(_InputIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
|
||||||
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) {
|
|
||||||
std::__invoke(__f, std::__invoke(__proj, *__first));
|
|
||||||
++__first;
|
|
||||||
--__n;
|
|
||||||
}
|
|
||||||
return std::move(__first);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class _RandIter,
|
|
||||||
class _Size,
|
|
||||||
class _Func,
|
|
||||||
class _Proj,
|
|
||||||
__enable_if_t<__has_random_access_iterator_category<_RandIter>::value, int> = 0>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandIter
|
|
||||||
__for_each_n(_RandIter __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
|
|
||||||
typename std::iterator_traits<_RandIter>::difference_type __n = __orig_n;
|
|
||||||
auto __last = __first + __n;
|
|
||||||
std::__for_each(__first, __last, __f, __proj);
|
|
||||||
return __last;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef _LIBCPP_CXX03_LANG
|
#ifndef _LIBCPP_CXX03_LANG
|
||||||
template <class _SegmentedIterator,
|
if constexpr (__is_segmented_iterator_v<_InputIterator>) {
|
||||||
class _Size,
|
using __local_iterator = typename __segmented_iterator_traits<_InputIterator>::__local_iterator;
|
||||||
class _Func,
|
if constexpr (__has_random_access_iterator_category<__local_iterator>::value) {
|
||||||
class _Proj,
|
return std::__for_each_n_segment(__first, __orig_n, [&](__local_iterator __lfirst, __local_iterator __llast) {
|
||||||
__enable_if_t<!__has_random_access_iterator_category<_SegmentedIterator>::value &&
|
std::__for_each(__lfirst, __llast, __f, __proj);
|
||||||
__is_segmented_iterator<_SegmentedIterator>::value &&
|
});
|
||||||
__has_random_access_iterator_category<
|
} else {
|
||||||
typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value,
|
return std::__for_each(__first, __first + __n, __f, __proj);
|
||||||
int> = 0>
|
}
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _SegmentedIterator
|
} else
|
||||||
__for_each_n(_SegmentedIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
|
#endif
|
||||||
using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator;
|
{
|
||||||
return std::__for_each_n_segment(__first, __orig_n, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
|
while (__n > 0) {
|
||||||
std::__for_each(__lfirst, __llast, __f, __proj);
|
std::__invoke(__f, std::__invoke(__proj, *__first));
|
||||||
});
|
++__first;
|
||||||
|
--__n;
|
||||||
|
}
|
||||||
|
return std::move(__first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // !_LIBCPP_CXX03_LANG
|
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 17
|
#if _LIBCPP_STD_VER >= 17
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
template <class _SegmentedIterator, class _Size, class _Functor>
|
template <class _SegmentedIterator, class _Size, class _Functor>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator
|
||||||
__for_each_n_segment(_SegmentedIterator __first, _Size __orig_n, _Functor __func) {
|
__for_each_n_segment(_SegmentedIterator __first, _Size __orig_n, _Functor __func) {
|
||||||
static_assert(__is_segmented_iterator<_SegmentedIterator>::value &&
|
static_assert(__is_segmented_iterator_v<_SegmentedIterator> &&
|
||||||
__has_random_access_iterator_category<
|
__has_random_access_iterator_category<
|
||||||
typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value,
|
typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value,
|
||||||
"__for_each_n_segment only works with segmented iterators with random-access local iterators");
|
"__for_each_n_segment only works with segmented iterators with random-access local iterators");
|
||||||
|
|||||||
@@ -48,6 +48,32 @@ __for_each_segment(_SegmentedIterator __first, _SegmentedIterator __last, _Funct
|
|||||||
__func(_Traits::__begin(__sfirst), _Traits::__local(__last));
|
__func(_Traits::__begin(__sfirst), _Traits::__local(__last));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class _SegmentedIterator, class _Functor>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
||||||
|
__for_each_segment_backward(_SegmentedIterator __first, _SegmentedIterator __last, _Functor __func) {
|
||||||
|
using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
|
||||||
|
|
||||||
|
auto __sfirst = _Traits::__segment(__first);
|
||||||
|
auto __slast = _Traits::__segment(__last);
|
||||||
|
|
||||||
|
// We are in a single segment, so we might not be at the beginning or end
|
||||||
|
if (__sfirst == __slast) {
|
||||||
|
__func(_Traits::__local(__first), _Traits::__local(__last));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have more than one segment. Iterate over the last segment, since we might not start at the end
|
||||||
|
__func(_Traits::__begin(__slast), _Traits::__local(__last));
|
||||||
|
--__slast;
|
||||||
|
// iterate over the segments which are guaranteed to be completely in the range
|
||||||
|
while (__sfirst != __slast) {
|
||||||
|
__func(_Traits::__begin(__slast), _Traits::__end(__slast));
|
||||||
|
--__slast;
|
||||||
|
}
|
||||||
|
// iterate over the first segment
|
||||||
|
__func(_Traits::__local(__first), _Traits::__end(__slast));
|
||||||
|
}
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
#endif // _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
|
#endif // _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
|
||||||
|
|||||||
+4
-2
@@ -9,7 +9,9 @@
|
|||||||
#ifndef _LIBCPP___ALGORITHM_GENERATE_H
|
#ifndef _LIBCPP___ALGORITHM_GENERATE_H
|
||||||
#define _LIBCPP___ALGORITHM_GENERATE_H
|
#define _LIBCPP___ALGORITHM_GENERATE_H
|
||||||
|
|
||||||
|
#include <__algorithm/for_each.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__utility/forward.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
@@ -20,8 +22,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
template <class _ForwardIterator, class _Generator>
|
template <class _ForwardIterator, class _Generator>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||||
generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
|
generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
|
||||||
for (; __first != __last; ++__first)
|
using __iter_ref = decltype(*__first);
|
||||||
*__first = __gen();
|
std::for_each(__first, __last, [&](__iter_ref __element) { std::forward<__iter_ref>(__element) = __gen(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|||||||
+19
-6
@@ -9,25 +9,38 @@
|
|||||||
#ifndef _LIBCPP___ALGORITHM_GENERATE_N_H
|
#ifndef _LIBCPP___ALGORITHM_GENERATE_N_H
|
||||||
#define _LIBCPP___ALGORITHM_GENERATE_N_H
|
#define _LIBCPP___ALGORITHM_GENERATE_N_H
|
||||||
|
|
||||||
|
#include <__algorithm/for_each_n.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__utility/convert_to_integral.h>
|
#include <__functional/identity.h>
|
||||||
|
#include <__utility/forward.h>
|
||||||
|
#include <__utility/move.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
_LIBCPP_PUSH_MACROS
|
||||||
|
#include <__undef_macros>
|
||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
|
template <class _OutputIterator, class _Size, class _Generator>
|
||||||
|
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||||
|
__generate_n(_OutputIterator __first, _Size __orig_n, _Generator& __gen) {
|
||||||
|
using __iter_ref = decltype(*__first);
|
||||||
|
__identity __proj;
|
||||||
|
auto __f = [&](__iter_ref __element) { std::forward<__iter_ref>(__element) = __gen(); };
|
||||||
|
return std::__for_each_n(std::move(__first), __orig_n, __f, __proj);
|
||||||
|
}
|
||||||
|
|
||||||
template <class _OutputIterator, class _Size, class _Generator>
|
template <class _OutputIterator, class _Size, class _Generator>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _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;
|
return std::__generate_n(std::move(__first), __orig_n, __gen);
|
||||||
_IntegralSize __n = __orig_n;
|
|
||||||
for (; __n > 0; ++__first, (void)--__n)
|
|
||||||
*__first = __gen();
|
|
||||||
return __first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
|
_LIBCPP_POP_MACROS
|
||||||
|
|
||||||
#endif // _LIBCPP___ALGORITHM_GENERATE_N_H
|
#endif // _LIBCPP___ALGORITHM_GENERATE_N_H
|
||||||
|
|||||||
+4
-4
@@ -78,7 +78,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation_impl(
|
|||||||
_Pred&& __pred,
|
_Pred&& __pred,
|
||||||
_Proj1&& __proj1,
|
_Proj1&& __proj1,
|
||||||
_Proj2&& __proj2) {
|
_Proj2&& __proj2) {
|
||||||
using _D1 = __iter_diff_t<_Iter1>;
|
using _D1 = __iterator_difference_type<_Iter1>;
|
||||||
|
|
||||||
for (auto __i = __first1; __i != __last1; ++__i) {
|
for (auto __i = __first1; __i != __last1; ++__i) {
|
||||||
// Have we already counted the number of *__i in [f1, l1)?
|
// Have we already counted the number of *__i in [f1, l1)?
|
||||||
@@ -126,7 +126,7 @@ template <class _AlgPolicy, class _ForwardIterator1, class _Sentinel1, class _Fo
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// __first1 != __last1 && *__first1 != *__first2
|
// __first1 != __last1 && *__first1 != *__first2
|
||||||
using _D1 = __iter_diff_t<_ForwardIterator1>;
|
using _D1 = __iterator_difference_type<_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;
|
||||||
@@ -173,10 +173,10 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation(
|
|||||||
if (__first2 == __last2) // Second range is shorter
|
if (__first2 == __last2) // Second range is shorter
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
using _D1 = __iter_diff_t<_Iter1>;
|
using _D1 = __iterator_difference_type<_Iter1>;
|
||||||
_D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1);
|
_D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1);
|
||||||
|
|
||||||
using _D2 = __iter_diff_t<_Iter2>;
|
using _D2 = __iterator_difference_type<_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;
|
||||||
|
|||||||
@@ -219,6 +219,9 @@ private:
|
|||||||
template <class _AlgPolicy, class _Iter>
|
template <class _AlgPolicy, class _Iter>
|
||||||
using __policy_iter_diff_t _LIBCPP_NODEBUG = typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>;
|
using __policy_iter_diff_t _LIBCPP_NODEBUG = typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>;
|
||||||
|
|
||||||
|
template <class _AlgPolicy, class _Iter>
|
||||||
|
using __policy_value_type _LIBCPP_NODEBUG = typename _IterOps<_AlgPolicy>::template __value_type<_Iter>;
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
_LIBCPP_POP_MACROS
|
_LIBCPP_POP_MACROS
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ template <class _Tp,
|
|||||||
class _Proj2,
|
class _Proj2,
|
||||||
class _Comp,
|
class _Comp,
|
||||||
__enable_if_t<__desugars_to_v<__totally_ordered_less_tag, _Comp, _Tp, _Tp> && !is_volatile<_Tp>::value &&
|
__enable_if_t<__desugars_to_v<__totally_ordered_less_tag, _Comp, _Tp, _Tp> && !is_volatile<_Tp>::value &&
|
||||||
__libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value &&
|
__is_trivially_equality_comparable_v<_Tp, _Tp> && __is_identity<_Proj1>::value &&
|
||||||
__is_identity<_Proj1>::value && __is_identity<_Proj2>::value,
|
__is_identity<_Proj2>::value,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||||
__lexicographical_compare(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Tp* __last2, _Comp&, _Proj1&, _Proj2&) {
|
__lexicographical_compare(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Tp* __last2, _Comp&, _Proj1&, _Proj2&) {
|
||||||
|
|||||||
@@ -37,13 +37,13 @@ template <class _InputIterator1, class _InputIterator2, class _Cmp>
|
|||||||
_LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_fast_path(
|
_LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_fast_path(
|
||||||
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp)
|
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp)
|
||||||
-> decltype(__comp(*__first1, *__first2)) {
|
-> decltype(__comp(*__first1, *__first2)) {
|
||||||
static_assert(
|
static_assert(signed_integral<__iterator_difference_type<_InputIterator1>>,
|
||||||
signed_integral<__iter_diff_t<_InputIterator1>>, "Using a non-integral difference_type is undefined behavior.");
|
"Using a non-integral difference_type is undefined behavior.");
|
||||||
static_assert(
|
static_assert(signed_integral<__iterator_difference_type<_InputIterator2>>,
|
||||||
signed_integral<__iter_diff_t<_InputIterator2>>, "Using a non-integral difference_type is undefined behavior.");
|
"Using a non-integral difference_type is undefined behavior.");
|
||||||
|
|
||||||
using _Len1 = __iter_diff_t<_InputIterator1>;
|
using _Len1 = __iterator_difference_type<_InputIterator1>;
|
||||||
using _Len2 = __iter_diff_t<_InputIterator2>;
|
using _Len2 = __iterator_difference_type<_InputIterator2>;
|
||||||
using _Common = common_type_t<_Len1, _Len2>;
|
using _Common = common_type_t<_Len1, _Len2>;
|
||||||
|
|
||||||
_Len1 __len1 = __last1 - __first1;
|
_Len1 __len1 = __last1 - __first1;
|
||||||
|
|||||||
+16
-4
@@ -12,9 +12,11 @@
|
|||||||
#include <__algorithm/comp.h>
|
#include <__algorithm/comp.h>
|
||||||
#include <__algorithm/comp_ref_type.h>
|
#include <__algorithm/comp_ref_type.h>
|
||||||
#include <__algorithm/iterator_operations.h>
|
#include <__algorithm/iterator_operations.h>
|
||||||
|
#include <__algorithm/push_heap.h>
|
||||||
#include <__algorithm/sift_down.h>
|
#include <__algorithm/sift_down.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__iterator/iterator_traits.h>
|
#include <__iterator/iterator_traits.h>
|
||||||
|
#include <__type_traits/is_arithmetic.h>
|
||||||
#include <__utility/move.h>
|
#include <__utility/move.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
@@ -31,13 +33,23 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 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 __diff_t = __iterator_difference_type<_RandomAccessIterator>;
|
||||||
difference_type __n = __last - __first;
|
const __diff_t __n = __last - __first;
|
||||||
|
|
||||||
|
const bool __assume_both_children = is_arithmetic<__iterator_value_type<_RandomAccessIterator> >::value;
|
||||||
|
|
||||||
|
// While it would be correct to always assume we have both children, in practice we observed this to be a performance
|
||||||
|
// improvement only for arithmetic types.
|
||||||
|
const __diff_t __sift_down_n = __assume_both_children ? ((__n & 1) ? __n : __n - 1) : __n;
|
||||||
|
|
||||||
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) {
|
|
||||||
std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start);
|
for (__diff_t __start = (__sift_down_n - 2) / 2; __start >= 0; --__start) {
|
||||||
|
std::__sift_down<_AlgPolicy, __assume_both_children>(__first, __comp_ref, __sift_down_n, __start);
|
||||||
}
|
}
|
||||||
|
if _LIBCPP_CONSTEXPR (__assume_both_children)
|
||||||
|
std::__sift_up<_AlgPolicy>(__first, __last, __comp, __n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -60,7 +60,7 @@ __mismatch(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Pred& __pred, _Pro
|
|||||||
template <class _Iter>
|
template <class _Iter>
|
||||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter, _Iter>
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter, _Iter>
|
||||||
__mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
|
__mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
|
||||||
using __value_type = __iter_value_type<_Iter>;
|
using __value_type = __iterator_value_type<_Iter>;
|
||||||
constexpr size_t __unroll_count = 4;
|
constexpr size_t __unroll_count = 4;
|
||||||
constexpr size_t __vec_size = __native_vector_size<__value_type>;
|
constexpr size_t __vec_size = __native_vector_size<__value_type>;
|
||||||
using __vec = __simd_vector<__value_type, __vec_size>;
|
using __vec = __simd_vector<__value_type, __vec_size>;
|
||||||
@@ -136,7 +136,7 @@ template <class _Tp,
|
|||||||
class _Proj2,
|
class _Proj2,
|
||||||
__enable_if_t<!is_integral<_Tp>::value && __desugars_to_v<__equal_tag, _Pred, _Tp, _Tp> &&
|
__enable_if_t<!is_integral<_Tp>::value && __desugars_to_v<__equal_tag, _Pred, _Tp, _Tp> &&
|
||||||
__is_identity<_Proj1>::value && __is_identity<_Proj2>::value &&
|
__is_identity<_Proj1>::value && __is_identity<_Proj2>::value &&
|
||||||
__can_map_to_integer_v<_Tp> && __libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value,
|
__can_map_to_integer_v<_Tp> && __is_trivially_equality_comparable_v<_Tp, _Tp>,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*>
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*>
|
||||||
__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
|
__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
|
||||||
|
|||||||
+8
-19
@@ -50,37 +50,26 @@ struct __move_impl {
|
|||||||
return std::make_pair(std::move(__first), std::move(__result));
|
return std::make_pair(std::move(__first), std::move(__result));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _InIter, class _OutIter>
|
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
|
||||||
struct _MoveSegment {
|
|
||||||
using _Traits _LIBCPP_NODEBUG = __segmented_iterator_traits<_InIter>;
|
|
||||||
|
|
||||||
_OutIter& __result_;
|
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit _MoveSegment(_OutIter& __result)
|
|
||||||
: __result_(__result) {}
|
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
|
||||||
operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
|
|
||||||
__result_ = std::__move<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||||
std::__for_each_segment(__first, __last, _MoveSegment<_InIter, _OutIter>(__result));
|
using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
|
||||||
|
std::__for_each_segment(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
|
||||||
|
__result = std::__move<_AlgPolicy>(__lfirst, __llast, std::move(__result)).second;
|
||||||
|
});
|
||||||
return std::make_pair(__last, std::move(__result));
|
return std::make_pair(__last, std::move(__result));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _InIter,
|
template <class _InIter,
|
||||||
class _OutIter,
|
class _OutIter,
|
||||||
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
||||||
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
|
!__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||||
using _Traits = __segmented_iterator_traits<_OutIter>;
|
using _Traits = __segmented_iterator_traits<_OutIter>;
|
||||||
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
|
using _DiffT =
|
||||||
|
typename common_type<__iterator_difference_type<_InIter>, __iterator_difference_type<_OutIter> >::type;
|
||||||
|
|
||||||
if (__first == __last)
|
if (__first == __last)
|
||||||
return std::make_pair(std::move(__first), std::move(__result));
|
return std::make_pair(std::move(__first), std::move(__result));
|
||||||
|
|||||||
+9
-24
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <__algorithm/copy_backward.h>
|
#include <__algorithm/copy_backward.h>
|
||||||
#include <__algorithm/copy_move_common.h>
|
#include <__algorithm/copy_move_common.h>
|
||||||
|
#include <__algorithm/for_each_segment.h>
|
||||||
#include <__algorithm/iterator_operations.h>
|
#include <__algorithm/iterator_operations.h>
|
||||||
#include <__algorithm/min.h>
|
#include <__algorithm/min.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
@@ -51,42 +52,26 @@ struct __move_backward_impl {
|
|||||||
return std::make_pair(std::move(__original_last_iter), std::move(__result));
|
return std::make_pair(std::move(__original_last_iter), std::move(__result));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
|
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||||
using _Traits = __segmented_iterator_traits<_InIter>;
|
using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
|
||||||
auto __sfirst = _Traits::__segment(__first);
|
std::__for_each_segment_backward(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
|
||||||
auto __slast = _Traits::__segment(__last);
|
__result = std::__move_backward<_AlgPolicy>(std::move(__lfirst), std::move(__llast), std::move(__result)).second;
|
||||||
if (__sfirst == __slast) {
|
});
|
||||||
auto __iters =
|
|
||||||
std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
|
|
||||||
return std::make_pair(__last, __iters.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
__result =
|
|
||||||
std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
|
|
||||||
.second;
|
|
||||||
--__slast;
|
|
||||||
while (__sfirst != __slast) {
|
|
||||||
__result =
|
|
||||||
std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
|
|
||||||
.second;
|
|
||||||
--__slast;
|
|
||||||
}
|
|
||||||
__result = std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
|
|
||||||
.second;
|
|
||||||
return std::make_pair(__last, std::move(__result));
|
return std::make_pair(__last, std::move(__result));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _InIter,
|
template <class _InIter,
|
||||||
class _OutIter,
|
class _OutIter,
|
||||||
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
||||||
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
|
!__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||||
using _Traits = __segmented_iterator_traits<_OutIter>;
|
using _Traits = __segmented_iterator_traits<_OutIter>;
|
||||||
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
|
using _DiffT =
|
||||||
|
typename common_type<__iterator_difference_type<_InIter>, __iterator_difference_type<_OutIter> >::type;
|
||||||
|
|
||||||
// When the range contains no elements, __result might not be a valid iterator
|
// When the range contains no elements, __result might not be a valid iterator
|
||||||
if (__first == __last)
|
if (__first == __last)
|
||||||
|
|||||||
+4
-4
@@ -10,7 +10,9 @@
|
|||||||
#ifndef _LIBCPP___ALGORITHM_NONE_OF_H
|
#ifndef _LIBCPP___ALGORITHM_NONE_OF_H
|
||||||
#define _LIBCPP___ALGORITHM_NONE_OF_H
|
#define _LIBCPP___ALGORITHM_NONE_OF_H
|
||||||
|
|
||||||
|
#include <__algorithm/any_of.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__functional/identity.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
@@ -21,10 +23,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
template <class _InputIterator, class _Predicate>
|
template <class _InputIterator, class _Predicate>
|
||||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||||
none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||||
for (; __first != __last; ++__first)
|
__identity __proj;
|
||||||
if (__pred(*__first))
|
return !std::__any_of(__first, __last, __pred, __proj);
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|||||||
+1
-1
@@ -45,7 +45,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator __part
|
|||||||
for (; __i != __last; ++__i) {
|
for (; __i != __last; ++__i) {
|
||||||
if (__comp(*__i, *__first)) {
|
if (__comp(*__i, *__first)) {
|
||||||
_IterOps<_AlgPolicy>::iter_swap(__i, __first);
|
_IterOps<_AlgPolicy>::iter_swap(__i, __first);
|
||||||
std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first);
|
std::__sift_down<_AlgPolicy, false>(__first, __comp, __len, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp);
|
std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp);
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _Random
|
|||||||
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, false>(__result_first, __projected_comp, __len, 0);
|
||||||
}
|
}
|
||||||
std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
|
std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -115,7 +115,7 @@ template <class _ExecutionPolicy,
|
|||||||
class _Predicate,
|
class _Predicate,
|
||||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __iterator_difference_type<_ForwardIterator>
|
||||||
count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
|
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
|
||||||
_ForwardIterator, "count_if(first, last, pred) requires [first, last) to be ForwardIterators");
|
_ForwardIterator, "count_if(first, last, pred) requires [first, last) to be ForwardIterators");
|
||||||
@@ -129,7 +129,7 @@ template <class _ExecutionPolicy,
|
|||||||
class _Tp,
|
class _Tp,
|
||||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __iterator_difference_type<_ForwardIterator>
|
||||||
count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
|
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
|
||||||
_ForwardIterator, "count(first, last, val) requires [first, last) to be ForwardIterators");
|
_ForwardIterator, "count(first, last, val) requires [first, last) to be ForwardIterators");
|
||||||
@@ -144,7 +144,7 @@ template <class _ExecutionPolicy,
|
|||||||
class _Pred,
|
class _Pred,
|
||||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI bool
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
|
||||||
equal(_ExecutionPolicy&& __policy,
|
equal(_ExecutionPolicy&& __policy,
|
||||||
_ForwardIterator1 __first1,
|
_ForwardIterator1 __first1,
|
||||||
_ForwardIterator1 __last1,
|
_ForwardIterator1 __last1,
|
||||||
@@ -166,7 +166,7 @@ template <class _ExecutionPolicy,
|
|||||||
class _ForwardIterator2,
|
class _ForwardIterator2,
|
||||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI bool
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
|
||||||
equal(_ExecutionPolicy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
|
equal(_ExecutionPolicy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
|
||||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
|
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
|
||||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
|
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
|
||||||
@@ -185,7 +185,7 @@ template <class _ExecutionPolicy,
|
|||||||
class _Pred,
|
class _Pred,
|
||||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI bool
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
|
||||||
equal(_ExecutionPolicy&& __policy,
|
equal(_ExecutionPolicy&& __policy,
|
||||||
_ForwardIterator1 __first1,
|
_ForwardIterator1 __first1,
|
||||||
_ForwardIterator1 __last1,
|
_ForwardIterator1 __last1,
|
||||||
@@ -209,7 +209,7 @@ template <class _ExecutionPolicy,
|
|||||||
class _ForwardIterator2,
|
class _ForwardIterator2,
|
||||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI bool
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
|
||||||
equal(_ExecutionPolicy&& __policy,
|
equal(_ExecutionPolicy&& __policy,
|
||||||
_ForwardIterator1 __first1,
|
_ForwardIterator1 __first1,
|
||||||
_ForwardIterator1 __last1,
|
_ForwardIterator1 __last1,
|
||||||
@@ -259,7 +259,7 @@ template <class _ExecutionPolicy,
|
|||||||
class _Predicate,
|
class _Predicate,
|
||||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
||||||
find_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
find_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if requires ForwardIterators");
|
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if requires ForwardIterators");
|
||||||
using _Implementation = __pstl::__dispatch<__pstl::__find_if, __pstl::__current_configuration, _RawPolicy>;
|
using _Implementation = __pstl::__dispatch<__pstl::__find_if, __pstl::__current_configuration, _RawPolicy>;
|
||||||
@@ -272,7 +272,7 @@ template <class _ExecutionPolicy,
|
|||||||
class _Predicate,
|
class _Predicate,
|
||||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
||||||
find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if_not requires ForwardIterators");
|
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if_not requires ForwardIterators");
|
||||||
using _Implementation = __pstl::__dispatch<__pstl::__find_if_not, __pstl::__current_configuration, _RawPolicy>;
|
using _Implementation = __pstl::__dispatch<__pstl::__find_if_not, __pstl::__current_configuration, _RawPolicy>;
|
||||||
@@ -285,7 +285,7 @@ template <class _ExecutionPolicy,
|
|||||||
class _Tp,
|
class _Tp,
|
||||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
||||||
find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find requires ForwardIterators");
|
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find requires ForwardIterators");
|
||||||
using _Implementation = __pstl::__dispatch<__pstl::__find, __pstl::__current_configuration, _RawPolicy>;
|
using _Implementation = __pstl::__dispatch<__pstl::__find, __pstl::__current_configuration, _RawPolicy>;
|
||||||
|
|||||||
+27
-25
@@ -72,14 +72,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
#if _LIBCPP_STD_VER >= 14
|
#if _LIBCPP_STD_VER >= 14
|
||||||
|
|
||||||
template <class _InputIterator, class _OutputIterator>
|
template <class _InputIterator, class _OutputIterator>
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr pair<_OutputIterator, __iter_value_type<_InputIterator>>
|
_LIBCPP_HIDE_FROM_ABI constexpr pair<_OutputIterator, __iterator_value_type<_InputIterator>>
|
||||||
__partial_sum_max(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
|
__partial_sum_max(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
|
||||||
if (__first == __last)
|
if (__first == __last)
|
||||||
return {__result, 0};
|
return {__result, 0};
|
||||||
|
|
||||||
auto __max = *__first;
|
auto __max = *__first;
|
||||||
__iter_value_type<_InputIterator> __sum = *__first;
|
__iterator_value_type<_InputIterator> __sum = *__first;
|
||||||
*__result = __sum;
|
*__result = __sum;
|
||||||
|
|
||||||
while (++__first != __last) {
|
while (++__first != __last) {
|
||||||
if (__max < *__first) {
|
if (__max < *__first) {
|
||||||
@@ -124,7 +124,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __nth_radix(size_t __radix_number, _Radix _
|
|||||||
template <class _ForwardIterator, class _Map, class _RandomAccessIterator>
|
template <class _ForwardIterator, class _Map, class _RandomAccessIterator>
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr void
|
_LIBCPP_HIDE_FROM_ABI constexpr void
|
||||||
__collect(_ForwardIterator __first, _ForwardIterator __last, _Map __map, _RandomAccessIterator __counters) {
|
__collect(_ForwardIterator __first, _ForwardIterator __last, _Map __map, _RandomAccessIterator __counters) {
|
||||||
using __value_type = __iter_value_type<_ForwardIterator>;
|
using __value_type = __iterator_value_type<_ForwardIterator>;
|
||||||
using __traits = __counting_sort_traits<__value_type, _Map>;
|
using __traits = __counting_sort_traits<__value_type, _Map>;
|
||||||
|
|
||||||
std::for_each(__first, __last, [&__counters, &__map](const auto& __preimage) { ++__counters[__map(__preimage)]; });
|
std::for_each(__first, __last, [&__counters, &__map](const auto& __preimage) { ++__counters[__map(__preimage)]; });
|
||||||
@@ -160,7 +160,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __collect_impl(
|
|||||||
_RandomAccessIterator1 __counters,
|
_RandomAccessIterator1 __counters,
|
||||||
_RandomAccessIterator2 __maximums,
|
_RandomAccessIterator2 __maximums,
|
||||||
index_sequence<_Radices...>) {
|
index_sequence<_Radices...>) {
|
||||||
using __value_type = __iter_value_type<_ForwardIterator>;
|
using __value_type = __iterator_value_type<_ForwardIterator>;
|
||||||
constexpr auto __radix_value_range = __radix_sort_traits<__value_type, _Map, _Radix>::__radix_value_range;
|
constexpr auto __radix_value_range = __radix_sort_traits<__value_type, _Map, _Radix>::__radix_value_range;
|
||||||
|
|
||||||
auto __previous = numeric_limits<__invoke_result_t<_Map, __value_type>>::min();
|
auto __previous = numeric_limits<__invoke_result_t<_Map, __value_type>>::min();
|
||||||
@@ -189,7 +189,7 @@ __collect(_ForwardIterator __first,
|
|||||||
_Radix __radix,
|
_Radix __radix,
|
||||||
_RandomAccessIterator1 __counters,
|
_RandomAccessIterator1 __counters,
|
||||||
_RandomAccessIterator2 __maximums) {
|
_RandomAccessIterator2 __maximums) {
|
||||||
using __value_type = __iter_value_type<_ForwardIterator>;
|
using __value_type = __iterator_value_type<_ForwardIterator>;
|
||||||
constexpr auto __radix_count = __radix_sort_traits<__value_type, _Map, _Radix>::__radix_count;
|
constexpr auto __radix_count = __radix_sort_traits<__value_type, _Map, _Radix>::__radix_count;
|
||||||
return std::__collect_impl(
|
return std::__collect_impl(
|
||||||
__first, __last, __map, __radix, __counters, __maximums, make_index_sequence<__radix_count>());
|
__first, __last, __map, __radix, __counters, __maximums, make_index_sequence<__radix_count>());
|
||||||
@@ -213,10 +213,10 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __dispose_backward(
|
|||||||
template <class _ForwardIterator, class _RandomAccessIterator, class _Map>
|
template <class _ForwardIterator, class _RandomAccessIterator, class _Map>
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr _RandomAccessIterator
|
_LIBCPP_HIDE_FROM_ABI constexpr _RandomAccessIterator
|
||||||
__counting_sort_impl(_ForwardIterator __first, _ForwardIterator __last, _RandomAccessIterator __result, _Map __map) {
|
__counting_sort_impl(_ForwardIterator __first, _ForwardIterator __last, _RandomAccessIterator __result, _Map __map) {
|
||||||
using __value_type = __iter_value_type<_ForwardIterator>;
|
using __value_type = __iterator_value_type<_ForwardIterator>;
|
||||||
using __traits = __counting_sort_traits<__value_type, _Map>;
|
using __traits = __counting_sort_traits<__value_type, _Map>;
|
||||||
|
|
||||||
__iter_diff_t<_RandomAccessIterator> __counters[__traits::__value_range + 1] = {0};
|
__iterator_difference_type<_RandomAccessIterator> __counters[__traits::__value_range + 1] = {0};
|
||||||
|
|
||||||
std::__collect(__first, __last, __map, std::next(std::begin(__counters)));
|
std::__collect(__first, __last, __map, std::next(std::begin(__counters)));
|
||||||
std::__dispose(__first, __last, __result, __map, std::begin(__counters));
|
std::__dispose(__first, __last, __result, __map, std::begin(__counters));
|
||||||
@@ -224,12 +224,13 @@ __counting_sort_impl(_ForwardIterator __first, _ForwardIterator __last, _RandomA
|
|||||||
return __result + __counters[__traits::__value_range];
|
return __result + __counters[__traits::__value_range];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _RandomAccessIterator1,
|
template <
|
||||||
class _RandomAccessIterator2,
|
class _RandomAccessIterator1,
|
||||||
class _Map,
|
class _RandomAccessIterator2,
|
||||||
class _Radix,
|
class _Map,
|
||||||
enable_if_t< __radix_sort_traits<__iter_value_type<_RandomAccessIterator1>, _Map, _Radix>::__radix_count == 1,
|
class _Radix,
|
||||||
int> = 0>
|
enable_if_t<__radix_sort_traits<__iterator_value_type<_RandomAccessIterator1>, _Map, _Radix>::__radix_count == 1,
|
||||||
|
int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort_impl(
|
_LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort_impl(
|
||||||
_RandomAccessIterator1 __first,
|
_RandomAccessIterator1 __first,
|
||||||
_RandomAccessIterator1 __last,
|
_RandomAccessIterator1 __last,
|
||||||
@@ -243,24 +244,25 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort_impl(
|
|||||||
std::move(__buffer, __buffer_end, __first);
|
std::move(__buffer, __buffer_end, __first);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <class _RandomAccessIterator1,
|
||||||
class _RandomAccessIterator1,
|
class _RandomAccessIterator2,
|
||||||
class _RandomAccessIterator2,
|
class _Map,
|
||||||
class _Map,
|
class _Radix,
|
||||||
class _Radix,
|
enable_if_t<
|
||||||
enable_if_t< __radix_sort_traits<__iter_value_type<_RandomAccessIterator1>, _Map, _Radix>::__radix_count % 2 == 0,
|
__radix_sort_traits<__iterator_value_type<_RandomAccessIterator1>, _Map, _Radix>::__radix_count % 2 == 0,
|
||||||
int> = 0 >
|
int> = 0>
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort_impl(
|
_LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort_impl(
|
||||||
_RandomAccessIterator1 __first,
|
_RandomAccessIterator1 __first,
|
||||||
_RandomAccessIterator1 __last,
|
_RandomAccessIterator1 __last,
|
||||||
_RandomAccessIterator2 __buffer_begin,
|
_RandomAccessIterator2 __buffer_begin,
|
||||||
_Map __map,
|
_Map __map,
|
||||||
_Radix __radix) {
|
_Radix __radix) {
|
||||||
using __value_type = __iter_value_type<_RandomAccessIterator1>;
|
using __value_type = __iterator_value_type<_RandomAccessIterator1>;
|
||||||
using __traits = __radix_sort_traits<__value_type, _Map, _Radix>;
|
using __traits = __radix_sort_traits<__value_type, _Map, _Radix>;
|
||||||
|
|
||||||
__iter_diff_t<_RandomAccessIterator1> __counters[__traits::__radix_count][__traits::__radix_value_range] = {{0}};
|
__iterator_difference_type<_RandomAccessIterator1>
|
||||||
__iter_diff_t<_RandomAccessIterator1> __maximums[__traits::__radix_count] = {0};
|
__counters[__traits::__radix_count][__traits::__radix_value_range] = {{0}};
|
||||||
|
__iterator_difference_type<_RandomAccessIterator1> __maximums[__traits::__radix_count] = {0};
|
||||||
const auto __is_sorted = std::__collect(__first, __last, __map, __radix, __counters, __maximums);
|
const auto __is_sorted = std::__collect(__first, __last, __map, __radix, __counters, __maximums);
|
||||||
if (!__is_sorted) {
|
if (!__is_sorted) {
|
||||||
const auto __range_size = std::distance(__first, __last);
|
const auto __range_size = std::distance(__first, __last);
|
||||||
|
|||||||
+3
-26
@@ -9,16 +9,12 @@
|
|||||||
#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_N_H
|
#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_N_H
|
||||||
#define _LIBCPP___ALGORITHM_RANGES_COPY_N_H
|
#define _LIBCPP___ALGORITHM_RANGES_COPY_N_H
|
||||||
|
|
||||||
#include <__algorithm/copy.h>
|
#include <__algorithm/copy_n.h>
|
||||||
#include <__algorithm/in_out_result.h>
|
#include <__algorithm/in_out_result.h>
|
||||||
#include <__algorithm/iterator_operations.h>
|
#include <__algorithm/iterator_operations.h>
|
||||||
#include <__algorithm/ranges_copy.h>
|
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__functional/identity.h>
|
|
||||||
#include <__iterator/concepts.h>
|
#include <__iterator/concepts.h>
|
||||||
#include <__iterator/incrementable_traits.h>
|
#include <__iterator/incrementable_traits.h>
|
||||||
#include <__iterator/unreachable_sentinel.h>
|
|
||||||
#include <__iterator/wrap_iter.h>
|
|
||||||
#include <__utility/move.h>
|
#include <__utility/move.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
@@ -37,32 +33,13 @@ namespace ranges {
|
|||||||
template <class _Ip, class _Op>
|
template <class _Ip, class _Op>
|
||||||
using copy_n_result = in_out_result<_Ip, _Op>;
|
using copy_n_result = in_out_result<_Ip, _Op>;
|
||||||
|
|
||||||
// TODO: Merge this with copy_n
|
|
||||||
struct __copy_n {
|
struct __copy_n {
|
||||||
template <class _InIter, class _DiffType, class _OutIter>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
|
|
||||||
__go(_InIter __first, _DiffType __n, _OutIter __result) {
|
|
||||||
while (__n != 0) {
|
|
||||||
*__result = *__first;
|
|
||||||
++__first;
|
|
||||||
++__result;
|
|
||||||
--__n;
|
|
||||||
}
|
|
||||||
return {std::move(__first), std::move(__result)};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
|
|
||||||
__go(_InIter __first, _DiffType __n, _OutIter __result) {
|
|
||||||
auto __ret = std::__copy(__first, __first + __n, __result);
|
|
||||||
return {__ret.first, __ret.second};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <input_iterator _Ip, weakly_incrementable _Op>
|
template <input_iterator _Ip, weakly_incrementable _Op>
|
||||||
requires indirectly_copyable<_Ip, _Op>
|
requires indirectly_copyable<_Ip, _Op>
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op>
|
_LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op>
|
||||||
operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
|
operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
|
||||||
return __go(std::move(__first), __n, std::move(__result));
|
auto __res = std::__copy_n<_RangeAlgPolicy>(std::move(__first), __n, std::move(__result));
|
||||||
|
return {std::move(__res.first), std::move(__res.second)};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+17
-26
@@ -13,13 +13,12 @@
|
|||||||
#include <__algorithm/unwrap_range.h>
|
#include <__algorithm/unwrap_range.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__functional/identity.h>
|
#include <__functional/identity.h>
|
||||||
#include <__functional/invoke.h>
|
|
||||||
#include <__functional/ranges_operations.h>
|
#include <__functional/ranges_operations.h>
|
||||||
#include <__iterator/concepts.h>
|
#include <__iterator/concepts.h>
|
||||||
#include <__iterator/distance.h>
|
|
||||||
#include <__iterator/indirectly_comparable.h>
|
#include <__iterator/indirectly_comparable.h>
|
||||||
#include <__ranges/access.h>
|
#include <__ranges/access.h>
|
||||||
#include <__ranges/concepts.h>
|
#include <__ranges/concepts.h>
|
||||||
|
#include <__ranges/size.h>
|
||||||
#include <__utility/move.h>
|
#include <__utility/move.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
@@ -51,20 +50,17 @@ struct __equal {
|
|||||||
_Pred __pred = {},
|
_Pred __pred = {},
|
||||||
_Proj1 __proj1 = {},
|
_Proj1 __proj1 = {},
|
||||||
_Proj2 __proj2 = {}) const {
|
_Proj2 __proj2 = {}) const {
|
||||||
if constexpr (sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>) {
|
static constexpr bool __both_sized = sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>;
|
||||||
|
if constexpr (__both_sized) {
|
||||||
if (__last1 - __first1 != __last2 - __first2)
|
if (__last1 - __first1 != __last2 - __first2)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto __unwrapped1 = std::__unwrap_range(std::move(__first1), std::move(__last1));
|
|
||||||
auto __unwrapped2 = std::__unwrap_range(std::move(__first2), std::move(__last2));
|
auto [__ufirst1, __ulast1] = std::__unwrap_range(std::move(__first1), std::move(__last1));
|
||||||
return std::__equal_impl(
|
auto [__ufirst2, __ulast2] = std::__unwrap_range(std::move(__first2), std::move(__last2));
|
||||||
std::move(__unwrapped1.first),
|
|
||||||
std::move(__unwrapped1.second),
|
return std::__equal_impl<__both_sized>(
|
||||||
std::move(__unwrapped2.first),
|
std::move(__ufirst1), std::move(__ulast1), std::move(__ufirst2), std::move(__ulast2), __pred, __proj1, __proj2);
|
||||||
std::move(__unwrapped2.second),
|
|
||||||
__pred,
|
|
||||||
__proj1,
|
|
||||||
__proj2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <input_range _Range1,
|
template <input_range _Range1,
|
||||||
@@ -75,21 +71,16 @@ struct __equal {
|
|||||||
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
|
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
|
||||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
|
||||||
_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
|
_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
|
||||||
if constexpr (sized_range<_Range1> && sized_range<_Range2>) {
|
static constexpr bool __both_sized = sized_range<_Range1> && sized_range<_Range2>;
|
||||||
if (ranges::distance(__range1) != ranges::distance(__range2))
|
if constexpr (__both_sized) {
|
||||||
|
if (ranges::size(__range1) != ranges::size(__range2))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto __unwrapped1 = std::__unwrap_range(ranges::begin(__range1), ranges::end(__range1));
|
|
||||||
auto __unwrapped2 = std::__unwrap_range(ranges::begin(__range2), ranges::end(__range2));
|
auto [__ufirst1, __ulast1] = std::__unwrap_range(ranges::begin(__range1), ranges::end(__range1));
|
||||||
return std::__equal_impl(
|
auto [__ufirst2, __ulast2] = std::__unwrap_range(ranges::begin(__range2), ranges::end(__range2));
|
||||||
std::move(__unwrapped1.first),
|
return std::__equal_impl<__both_sized>(
|
||||||
std::move(__unwrapped1.second),
|
std::move(__ufirst1), std::move(__ulast1), std::move(__ufirst2), std::move(__ulast2), __pred, __proj1, __proj2);
|
||||||
std::move(__unwrapped2.first),
|
|
||||||
std::move(__unwrapped2.second),
|
|
||||||
__pred,
|
|
||||||
__proj1,
|
|
||||||
__proj2);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+7
-6
@@ -9,12 +9,14 @@
|
|||||||
#ifndef _LIBCPP___ALGORITHM_RANGES_FILL_H
|
#ifndef _LIBCPP___ALGORITHM_RANGES_FILL_H
|
||||||
#define _LIBCPP___ALGORITHM_RANGES_FILL_H
|
#define _LIBCPP___ALGORITHM_RANGES_FILL_H
|
||||||
|
|
||||||
#include <__algorithm/ranges_fill_n.h>
|
#include <__algorithm/fill.h>
|
||||||
|
#include <__algorithm/fill_n.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__iterator/concepts.h>
|
#include <__iterator/concepts.h>
|
||||||
#include <__ranges/access.h>
|
#include <__ranges/access.h>
|
||||||
#include <__ranges/concepts.h>
|
#include <__ranges/concepts.h>
|
||||||
#include <__ranges/dangling.h>
|
#include <__ranges/dangling.h>
|
||||||
|
#include <__utility/move.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
@@ -31,12 +33,11 @@ namespace ranges {
|
|||||||
struct __fill {
|
struct __fill {
|
||||||
template <class _Type, output_iterator<const _Type&> _Iter, sentinel_for<_Iter> _Sent>
|
template <class _Type, output_iterator<const _Type&> _Iter, sentinel_for<_Iter> _Sent>
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const {
|
_LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const {
|
||||||
if constexpr (random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) {
|
if constexpr (sized_sentinel_for<_Sent, _Iter>) {
|
||||||
return ranges::fill_n(__first, __last - __first, __value);
|
auto __n = __last - __first;
|
||||||
|
return std::__fill_n(std::move(__first), __n, __value);
|
||||||
} else {
|
} else {
|
||||||
for (; __first != __last; ++__first)
|
return std::__fill(std::move(__first), std::move(__last), __value);
|
||||||
*__first = __value;
|
|
||||||
return __first;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-1
@@ -12,6 +12,7 @@
|
|||||||
#include <__algorithm/for_each.h>
|
#include <__algorithm/for_each.h>
|
||||||
#include <__algorithm/for_each_n.h>
|
#include <__algorithm/for_each_n.h>
|
||||||
#include <__algorithm/in_fun_result.h>
|
#include <__algorithm/in_fun_result.h>
|
||||||
|
#include <__algorithm/specialized_algorithms.h>
|
||||||
#include <__concepts/assignable.h>
|
#include <__concepts/assignable.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__functional/identity.h>
|
#include <__functional/identity.h>
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
#include <__ranges/access.h>
|
#include <__ranges/access.h>
|
||||||
#include <__ranges/concepts.h>
|
#include <__ranges/concepts.h>
|
||||||
#include <__ranges/dangling.h>
|
#include <__ranges/dangling.h>
|
||||||
|
#include <__type_traits/remove_cvref.h>
|
||||||
#include <__utility/move.h>
|
#include <__utility/move.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
@@ -71,7 +73,13 @@ public:
|
|||||||
indirectly_unary_invocable<projected<iterator_t<_Range>, _Proj>> _Func>
|
indirectly_unary_invocable<projected<iterator_t<_Range>, _Proj>> _Func>
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr for_each_result<borrowed_iterator_t<_Range>, _Func>
|
_LIBCPP_HIDE_FROM_ABI constexpr for_each_result<borrowed_iterator_t<_Range>, _Func>
|
||||||
operator()(_Range&& __range, _Func __func, _Proj __proj = {}) const {
|
operator()(_Range&& __range, _Func __func, _Proj __proj = {}) const {
|
||||||
return __for_each_impl(ranges::begin(__range), ranges::end(__range), __func, __proj);
|
using _SpecialAlg = __specialized_algorithm<_Algorithm::__for_each, __single_range<remove_cvref_t<_Range>>>;
|
||||||
|
if constexpr (_SpecialAlg::__has_algorithm) {
|
||||||
|
auto [__iter, __func2] = _SpecialAlg()(__range, std::move(__func), std::move(__proj));
|
||||||
|
return {std::move(__iter), std::move(__func)};
|
||||||
|
} else {
|
||||||
|
return __for_each_impl(ranges::begin(__range), ranges::end(__range), __func, __proj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+2
-6
@@ -9,6 +9,7 @@
|
|||||||
#ifndef _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H
|
#ifndef _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H
|
||||||
#define _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H
|
#define _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H
|
||||||
|
|
||||||
|
#include <__algorithm/generate_n.h>
|
||||||
#include <__concepts/constructible.h>
|
#include <__concepts/constructible.h>
|
||||||
#include <__concepts/invocable.h>
|
#include <__concepts/invocable.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
@@ -38,12 +39,7 @@ struct __generate_n {
|
|||||||
requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>>
|
requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>>
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr _OutIter
|
_LIBCPP_HIDE_FROM_ABI constexpr _OutIter
|
||||||
operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const {
|
operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const {
|
||||||
for (; __n > 0; --__n) {
|
return std::__generate_n(std::move(__first), __n, __gen);
|
||||||
*__first = __gen();
|
|
||||||
++__first;
|
|
||||||
}
|
|
||||||
|
|
||||||
return __first;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -54,8 +54,8 @@ struct __search_n {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (random_access_iterator<_Iter1>) {
|
if constexpr (random_access_iterator<_Iter1>) {
|
||||||
auto __ret = std::__search_n_random_access_impl<_RangeAlgPolicy>(
|
auto __ret =
|
||||||
__first, __last, __count, __value, __pred, __proj, __size);
|
std::__search_n_random_access_impl<_RangeAlgPolicy>(__first, __count, __value, __pred, __proj, __size);
|
||||||
return {std::move(__ret.first), std::move(__ret.second)};
|
return {std::move(__ret.first), std::move(__ret.second)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-42
@@ -12,16 +12,13 @@
|
|||||||
#include <__algorithm/copy.h>
|
#include <__algorithm/copy.h>
|
||||||
#include <__algorithm/copy_backward.h>
|
#include <__algorithm/copy_backward.h>
|
||||||
#include <__algorithm/iterator_operations.h>
|
#include <__algorithm/iterator_operations.h>
|
||||||
|
#include <__algorithm/min.h>
|
||||||
#include <__algorithm/move.h>
|
#include <__algorithm/move.h>
|
||||||
#include <__algorithm/move_backward.h>
|
#include <__algorithm/move_backward.h>
|
||||||
#include <__algorithm/swap_ranges.h>
|
#include <__algorithm/swap_ranges.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__cstddef/size_t.h>
|
|
||||||
#include <__fwd/bit_reference.h>
|
#include <__fwd/bit_reference.h>
|
||||||
#include <__iterator/iterator_traits.h>
|
#include <__iterator/iterator_traits.h>
|
||||||
#include <__memory/construct_at.h>
|
|
||||||
#include <__memory/pointer_traits.h>
|
|
||||||
#include <__type_traits/is_constant_evaluated.h>
|
|
||||||
#include <__type_traits/is_trivially_assignable.h>
|
#include <__type_traits/is_trivially_assignable.h>
|
||||||
#include <__utility/move.h>
|
#include <__utility/move.h>
|
||||||
#include <__utility/pair.h>
|
#include <__utility/pair.h>
|
||||||
@@ -89,46 +86,32 @@ __rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIt
|
|||||||
return __r;
|
return __r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _Integral>
|
template <class _AlgPolicy, class _Iter, class _Sent>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral __algo_gcd(_Integral __x, _Integral __y) {
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Iter
|
||||||
do {
|
__rotate_random_access(_Iter __first, _Iter __middle, _Sent __sent) {
|
||||||
_Integral __t = __x % __y;
|
auto __left = _IterOps<_AlgPolicy>::distance(__first, __middle);
|
||||||
__x = __y;
|
auto __right = _IterOps<_AlgPolicy>::distance(__middle, __sent);
|
||||||
__y = __t;
|
auto __last = __first + __right;
|
||||||
} while (__y);
|
|
||||||
return __x;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class _AlgPolicy, typename _RandomAccessIterator>
|
auto __min_len = std::min(__left, __right);
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _RandomAccessIterator
|
|
||||||
__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) {
|
|
||||||
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
|
|
||||||
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
|
|
||||||
using _Ops = _IterOps<_AlgPolicy>;
|
|
||||||
|
|
||||||
const difference_type __m1 = __middle - __first;
|
while (__min_len > 0) {
|
||||||
const difference_type __m2 = _Ops::distance(__middle, __last);
|
if (__left <= __right) {
|
||||||
if (__m1 == __m2) {
|
do {
|
||||||
std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last);
|
std::__swap_ranges<_AlgPolicy>(__first, __first + __left, __first + __left);
|
||||||
return __middle;
|
__first += __left;
|
||||||
|
__right -= __left;
|
||||||
|
} while (__left <= __right);
|
||||||
|
__min_len = __right;
|
||||||
|
} else {
|
||||||
|
do {
|
||||||
|
std::__swap_ranges<_AlgPolicy>(__first + (__left - __right), __first + __left, __first + __left);
|
||||||
|
__left -= __right;
|
||||||
|
} while (__left > __right);
|
||||||
|
__min_len = __left;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const difference_type __g = std::__algo_gcd(__m1, __m2);
|
return __last;
|
||||||
for (_RandomAccessIterator __p = __first + __g; __p != __first;) {
|
|
||||||
value_type __t(_Ops::__iter_move(--__p));
|
|
||||||
_RandomAccessIterator __p1 = __p;
|
|
||||||
_RandomAccessIterator __p2 = __p1 + __m1;
|
|
||||||
do {
|
|
||||||
*__p1 = _Ops::__iter_move(__p2);
|
|
||||||
__p1 = __p2;
|
|
||||||
const difference_type __d = _Ops::distance(__p2, __last);
|
|
||||||
if (__m1 < __d)
|
|
||||||
__p2 += __m1;
|
|
||||||
else
|
|
||||||
__p2 = __first + (__m1 - __d);
|
|
||||||
} while (__p2 != __p);
|
|
||||||
*__p1 = std::move(__t);
|
|
||||||
}
|
|
||||||
return __first + __m2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _AlgPolicy, class _ForwardIterator>
|
template <class _AlgPolicy, class _ForwardIterator>
|
||||||
@@ -170,7 +153,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator
|
|||||||
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_random_access<_AlgPolicy>(__first, __middle, __last);
|
||||||
}
|
}
|
||||||
return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
|
return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-37
@@ -14,11 +14,7 @@
|
|||||||
#include <__algorithm/iterator_operations.h>
|
#include <__algorithm/iterator_operations.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__functional/identity.h>
|
#include <__functional/identity.h>
|
||||||
#include <__iterator/advance.h>
|
|
||||||
#include <__iterator/concepts.h>
|
|
||||||
#include <__iterator/distance.h>
|
|
||||||
#include <__iterator/iterator_traits.h>
|
#include <__iterator/iterator_traits.h>
|
||||||
#include <__ranges/concepts.h>
|
|
||||||
#include <__type_traits/enable_if.h>
|
#include <__type_traits/enable_if.h>
|
||||||
#include <__type_traits/invoke.h>
|
#include <__type_traits/invoke.h>
|
||||||
#include <__type_traits/is_callable.h>
|
#include <__type_traits/is_callable.h>
|
||||||
@@ -68,44 +64,60 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> __search_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj, class _DiffT>
|
// Finds the longest suffix in [__first, __last) where each element satisfies __pred.
|
||||||
|
template <class _RAIter, class _Pred, class _Proj, class _ValueT>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RAIter
|
||||||
|
__find_longest_suffix(_RAIter __first, _RAIter __last, const _ValueT& __value, _Pred& __pred, _Proj& __proj) {
|
||||||
|
while (__first != __last) {
|
||||||
|
if (!std::__invoke(__pred, std::__invoke(__proj, *--__last), __value)) {
|
||||||
|
return ++__last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return __first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _AlgPolicy, class _Pred, class _Iter, class _SizeT, class _Type, class _Proj, class _DiffT>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 std::pair<_Iter, _Iter> __search_n_random_access_impl(
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 std::pair<_Iter, _Iter> __search_n_random_access_impl(
|
||||||
_Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj, _DiffT __size1) {
|
_Iter __first, _SizeT __count_in, const _Type& __value, _Pred& __pred, _Proj& __proj, _DiffT __size) {
|
||||||
using difference_type = typename iterator_traits<_Iter>::difference_type;
|
auto __last = __first + __size;
|
||||||
|
auto __count = static_cast<_DiffT>(__count_in);
|
||||||
|
|
||||||
if (__count == 0)
|
if (__count == 0)
|
||||||
return std::make_pair(__first, __first);
|
return std::make_pair(__first, __first);
|
||||||
if (__size1 < static_cast<_DiffT>(__count)) {
|
if (__size < __count)
|
||||||
_IterOps<_AlgPolicy>::__advance_to(__first, __last);
|
return std::make_pair(__last, __last);
|
||||||
return std::make_pair(__first, __first);
|
|
||||||
}
|
// [__match_start, __match_start + __count) is the subrange which we currently check whether it only contains matching
|
||||||
|
// elements. This subrange is returned in case all the elements match.
|
||||||
|
// [__match_start, __matched_until) is the longest subrange where all elements are known to match at any given point
|
||||||
|
// in time.
|
||||||
|
// [__matched_until, __match_start + __count) is the subrange where we don't know whether the elements match.
|
||||||
|
|
||||||
|
// This algorithm tries to expand the subrange [__match_start, __matched_until) into a range of sufficient length.
|
||||||
|
// When we fail to do that because we find a mismatching element, we move it forward to the beginning of the next
|
||||||
|
// consecutive sequence that is not known not to match.
|
||||||
|
|
||||||
|
const _Iter __try_match_until = __last - __count;
|
||||||
|
_Iter __match_start = __first;
|
||||||
|
_Iter __matched_until = __first;
|
||||||
|
|
||||||
const auto __s = __first + __size1 - difference_type(__count - 1); // Start of pattern match can't go beyond here
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// Find first element in sequence that matchs __value, with a mininum of loop checks
|
// There's no chance of expanding the subrange into a sequence of sufficient length, since we don't have enough
|
||||||
while (true) {
|
// elements in the haystack anymore.
|
||||||
if (__first >= __s) { // return __last if no element matches __value
|
if (__match_start > __try_match_until)
|
||||||
_IterOps<_AlgPolicy>::__advance_to(__first, __last);
|
return std::make_pair(__last, __last);
|
||||||
return std::make_pair(__first, __first);
|
|
||||||
}
|
|
||||||
if (std::__invoke(__pred, std::__invoke(__proj, *__first), __value))
|
|
||||||
break;
|
|
||||||
++__first;
|
|
||||||
}
|
|
||||||
// *__first matches __value_, now match elements after here
|
|
||||||
auto __m = __first;
|
|
||||||
_SizeT __c(0);
|
|
||||||
while (true) {
|
|
||||||
if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern)
|
|
||||||
return std::make_pair(__first, __first + _DiffT(__count));
|
|
||||||
++__m; // no need to check range on __m because __s guarantees we have enough source
|
|
||||||
|
|
||||||
// if there is a mismatch, restart with a new __first
|
auto __mismatch = std::__find_longest_suffix(__matched_until, __match_start + __count, __value, __pred, __proj);
|
||||||
if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) {
|
|
||||||
__first = __m;
|
// If all elements in [__matched_until, __match_start + __count) match, we know that
|
||||||
++__first;
|
// [__match_start, __match_start + __count) is a full sequence of matching elements, so we're done.
|
||||||
break;
|
if (__mismatch == __matched_until)
|
||||||
} // else there is a match, check next elements
|
return std::make_pair(__match_start, __match_start + __count);
|
||||||
}
|
|
||||||
|
// Otherwise, we have to move the [__match_start, __matched_until) subrange forward past the point where we know for
|
||||||
|
// sure a match is impossible.
|
||||||
|
__matched_until = __match_start + __count;
|
||||||
|
__match_start = __mismatch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +131,7 @@ template <class _Iter,
|
|||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter>
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter>
|
||||||
__search_n_impl(_Iter __first, _Sent __last, _DiffT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) {
|
__search_n_impl(_Iter __first, _Sent __last, _DiffT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) {
|
||||||
return std::__search_n_random_access_impl<_ClassicAlgPolicy>(
|
return std::__search_n_random_access_impl<_ClassicAlgPolicy>(
|
||||||
__first, __last, __count, __value, __pred, __proj, __last - __first);
|
__first, __count, __value, __pred, __proj, __last - __first);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Iter1,
|
template <class _Iter1,
|
||||||
|
|||||||
+19
-18
@@ -24,59 +24,60 @@ _LIBCPP_PUSH_MACROS
|
|||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
template <class _AlgPolicy, bool __assume_both_children, 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,
|
__sift_down(_RandomAccessIterator __first,
|
||||||
_Compare&& __comp,
|
_Compare&& __comp,
|
||||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len,
|
__iterator_difference_type<_RandomAccessIterator> __len,
|
||||||
_RandomAccessIterator __start) {
|
__iterator_difference_type<_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;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
|
if _LIBCPP_CONSTEXPR (__assume_both_children) {
|
||||||
|
// right-child exists and is greater than left-child
|
||||||
|
__child += __comp(__first[__child], __first[__child + 1]);
|
||||||
|
} else if ((__child + 1) < __len && __comp(__first[__child], __first[__child + 1])) {
|
||||||
// right-child exists and is greater than left-child
|
// right-child exists and is greater than left-child
|
||||||
++__child_i;
|
|
||||||
++__child;
|
++__child;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we are in heap-order
|
// check if we are in heap-order
|
||||||
if (__comp(*__child_i, *__start))
|
if (__comp(__first[__child], __first[__start]))
|
||||||
// we are, __start is larger than its largest child
|
// we are, __start is larger than its largest child
|
||||||
return;
|
return;
|
||||||
|
|
||||||
value_type __top(_Ops::__iter_move(__start));
|
value_type __top(_Ops::__iter_move(__first + __start));
|
||||||
do {
|
do {
|
||||||
// we are not in heap-order, swap the parent with its largest child
|
// we are not in heap-order, swap the parent with its largest child
|
||||||
*__start = _Ops::__iter_move(__child_i);
|
__first[__start] = _Ops::__iter_move(__first + __child);
|
||||||
__start = __child_i;
|
__start = __child;
|
||||||
|
|
||||||
if ((__len - 2) / 2 < __child)
|
if ((__len - 2) / 2 < __child)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// recompute the child based off of the updated parent
|
// recompute the child based off of the updated parent
|
||||||
__child = 2 * __child + 1;
|
__child = 2 * __child + 1;
|
||||||
__child_i = __first + __child;
|
|
||||||
|
|
||||||
if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
|
if _LIBCPP_CONSTEXPR (__assume_both_children) {
|
||||||
|
__child += __comp(__first[__child], __first[__child + 1]);
|
||||||
|
} else if ((__child + 1) < __len && __comp(__first[__child], __first[__child + 1])) {
|
||||||
// right-child exists and is greater than left-child
|
// right-child exists and is greater than left-child
|
||||||
++__child_i;
|
|
||||||
++__child;
|
++__child;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we are in heap-order
|
// check if we are in heap-order
|
||||||
} while (!__comp(*__child_i, __top));
|
} while (!__comp(__first[__child], __top));
|
||||||
*__start = std::move(__top);
|
__first[__start] = std::move(__top);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
||||||
|
|||||||
+33
-4
@@ -26,9 +26,7 @@ _LIBCPP_PUSH_MACROS
|
|||||||
#include <__undef_macros>
|
#include <__undef_macros>
|
||||||
|
|
||||||
// TODO: Find out how altivec changes things and allow vectorizations there too.
|
// TODO: Find out how altivec changes things and allow vectorizations there too.
|
||||||
// TODO: Simplify this condition once we stop building with AppleClang 15 in the CI.
|
#if _LIBCPP_STD_VER >= 14 && defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(__ALTIVEC__)
|
||||||
#if _LIBCPP_STD_VER >= 14 && defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(__ALTIVEC__) && \
|
|
||||||
!(defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600)
|
|
||||||
# define _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS 1
|
# define _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS 1
|
||||||
#else
|
#else
|
||||||
# define _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS 0
|
# define _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS 0
|
||||||
@@ -116,16 +114,47 @@ template <class _VecT, class _Iter>
|
|||||||
}(make_index_sequence<__simd_vector_size_v<_VecT>>{});
|
}(make_index_sequence<__simd_vector_size_v<_VecT>>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load the first _Np elements, zero the rest
|
||||||
|
_LIBCPP_DIAGNOSTIC_PUSH
|
||||||
|
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpsabi")
|
||||||
|
template <class _VecT, size_t _Np, class _Iter>
|
||||||
|
[[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _VecT __partial_load(_Iter __iter) noexcept {
|
||||||
|
return [=]<size_t... _LoadIndices, size_t... _ZeroIndices>(
|
||||||
|
index_sequence<_LoadIndices...>, index_sequence<_ZeroIndices...>) _LIBCPP_ALWAYS_INLINE noexcept {
|
||||||
|
return _VecT{__iter[_LoadIndices]..., ((void)_ZeroIndices, 0)...};
|
||||||
|
}(make_index_sequence<_Np>{}, make_index_sequence<__simd_vector_size_v<_VecT> - _Np>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a vector where every elements is __val
|
||||||
|
template <class _VecT>
|
||||||
|
[[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _VecT
|
||||||
|
__broadcast(__simd_vector_underlying_type_t<_VecT> __val) {
|
||||||
|
return [&]<std::size_t... _Indices>(index_sequence<_Indices...>) {
|
||||||
|
return _VecT{((void)_Indices, __val)...};
|
||||||
|
}(make_index_sequence<__simd_vector_size_v<_VecT>>());
|
||||||
|
}
|
||||||
|
_LIBCPP_DIAGNOSTIC_POP
|
||||||
|
|
||||||
|
template <class _Tp, size_t _Np>
|
||||||
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __any_of(__simd_vector<_Tp, _Np> __vec) noexcept {
|
||||||
|
return __builtin_reduce_or(__builtin_convertvector(__vec, __simd_vector<bool, _Np>));
|
||||||
|
}
|
||||||
|
|
||||||
template <class _Tp, size_t _Np>
|
template <class _Tp, size_t _Np>
|
||||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __all_of(__simd_vector<_Tp, _Np> __vec) noexcept {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __all_of(__simd_vector<_Tp, _Np> __vec) noexcept {
|
||||||
return __builtin_reduce_and(__builtin_convertvector(__vec, __simd_vector<bool, _Np>));
|
return __builtin_reduce_and(__builtin_convertvector(__vec, __simd_vector<bool, _Np>));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class _Tp, size_t _Np>
|
||||||
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __none_of(__simd_vector<_Tp, _Np> __vec) noexcept {
|
||||||
|
return !__builtin_reduce_or(__builtin_convertvector(__vec, __simd_vector<bool, _Np>));
|
||||||
|
}
|
||||||
|
|
||||||
template <class _Tp, size_t _Np>
|
template <class _Tp, size_t _Np>
|
||||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t __find_first_set(__simd_vector<_Tp, _Np> __vec) noexcept {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t __find_first_set(__simd_vector<_Tp, _Np> __vec) noexcept {
|
||||||
using __mask_vec = __simd_vector<bool, _Np>;
|
using __mask_vec = __simd_vector<bool, _Np>;
|
||||||
|
|
||||||
// This has MSan disabled du to https://github.com/llvm/llvm-project/issues/85876
|
// This has MSan disabled du to https://llvm.org/PR85876
|
||||||
auto __impl = [&]<class _MaskT>(_MaskT) _LIBCPP_NO_SANITIZE("memory") noexcept {
|
auto __impl = [&]<class _MaskT>(_MaskT) _LIBCPP_NO_SANITIZE("memory") noexcept {
|
||||||
# if defined(_LIBCPP_BIG_ENDIAN)
|
# if defined(_LIBCPP_BIG_ENDIAN)
|
||||||
return std::min<size_t>(
|
return std::min<size_t>(
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef _LIBCPP___ALGORITHM_SPECIALIZED_ALGORITHMS_H
|
||||||
|
#define _LIBCPP___ALGORITHM_SPECIALIZED_ALGORITHMS_H
|
||||||
|
|
||||||
|
#include <__config>
|
||||||
|
|
||||||
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
|
# pragma GCC system_header
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
|
namespace _Algorithm {
|
||||||
|
struct __copy {};
|
||||||
|
struct __fill_n {};
|
||||||
|
struct __for_each {};
|
||||||
|
} // namespace _Algorithm
|
||||||
|
|
||||||
|
template <class>
|
||||||
|
struct __single_iterator;
|
||||||
|
|
||||||
|
template <class, class>
|
||||||
|
struct __iterator_pair;
|
||||||
|
|
||||||
|
template <class>
|
||||||
|
struct __single_range;
|
||||||
|
|
||||||
|
// This struct allows specializing algorithms for specific arguments. This is useful when we know a more efficient
|
||||||
|
// algorithm implementation for e.g. library-defined iterators. _Alg is one of tags defined inside the _Algorithm
|
||||||
|
// namespace above. _Ranges is an essentially arbitrary subset of the arguments to the algorithm that are used for
|
||||||
|
// dispatching. This set is specific to the algorithm: look at each algorithm to see which arguments they use for
|
||||||
|
// dispatching to specialized algorithms.
|
||||||
|
//
|
||||||
|
// A specialization of `__specialized_algorithm` has to define `__has_algorithm` to true for the specialized algorithm
|
||||||
|
// to be used. This is intended for cases where iterators can do generic unwrapping and forward to a different
|
||||||
|
// specialization of `__specialized_algorithm`.
|
||||||
|
//
|
||||||
|
// If __has_algorithm is true, there has to be an operator() which will get called with the actual arguments to the
|
||||||
|
// algorithm.
|
||||||
|
template <class _Alg, class... _Ranges>
|
||||||
|
struct __specialized_algorithm {
|
||||||
|
static const bool __has_algorithm = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
|
#endif // _LIBCPP___ALGORITHM_SPECIALIZED_ALGORITHMS_H
|
||||||
+1
-1
@@ -247,7 +247,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void __stable_sort(
|
|||||||
constexpr auto __default_comp = __desugars_to_v<__less_tag, _Compare, value_type, value_type >;
|
constexpr auto __default_comp = __desugars_to_v<__less_tag, _Compare, value_type, value_type >;
|
||||||
constexpr auto __radix_sortable =
|
constexpr auto __radix_sortable =
|
||||||
__is_ordered_integer_representable_v<value_type> &&
|
__is_ordered_integer_representable_v<value_type> &&
|
||||||
is_same_v< value_type&, __iter_reference<_RandomAccessIterator>>;
|
is_same_v< value_type&, __iterator_reference<_RandomAccessIterator>>;
|
||||||
if constexpr (__default_comp && __radix_sortable) {
|
if constexpr (__default_comp && __radix_sortable) {
|
||||||
if (__len <= __buff_size && __len >= static_cast<difference_type>(std::__radix_sort_min_bound<value_type>()) &&
|
if (__len <= __buff_size && __len >= static_cast<difference_type>(std::__radix_sort_min_bound<value_type>()) &&
|
||||||
__len <= static_cast<difference_type>(std::__radix_sort_max_bound<value_type>())) {
|
__len <= static_cast<difference_type>(std::__radix_sort_max_bound<value_type>())) {
|
||||||
|
|||||||
+31
-4
@@ -16,6 +16,7 @@
|
|||||||
# include <__cxx03/__verbose_trap>
|
# include <__cxx03/__verbose_trap>
|
||||||
#else
|
#else
|
||||||
# include <__config>
|
# include <__config>
|
||||||
|
# include <__log_hardening_failure>
|
||||||
# include <__verbose_abort>
|
# include <__verbose_abort>
|
||||||
# include <__verbose_trap>
|
# include <__verbose_trap>
|
||||||
#endif
|
#endif
|
||||||
@@ -24,14 +25,40 @@
|
|||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
|
#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
|
||||||
|
|
||||||
# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_ABORT("%s", message)
|
// Keep the old implementation that doesn't support assertion semantics for backward compatibility with the frozen C++03
|
||||||
|
// mode.
|
||||||
|
# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
|
||||||
|
# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_ABORT("%s", message)
|
||||||
|
# else
|
||||||
|
# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message)
|
||||||
|
# endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message)
|
# if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_IGNORE
|
||||||
|
# define _LIBCPP_ASSERTION_HANDLER(message) ((void)0)
|
||||||
|
|
||||||
#endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
|
# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE
|
||||||
|
# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_LOG_HARDENING_FAILURE(message)
|
||||||
|
|
||||||
|
# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
|
||||||
|
# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message)
|
||||||
|
|
||||||
|
# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
|
||||||
|
# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_ABORT("%s", message)
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
# error _LIBCPP_ASSERTION_SEMANTIC must be set to one of the following values: \
|
||||||
|
_LIBCPP_ASSERTION_SEMANTIC_IGNORE, \
|
||||||
|
_LIBCPP_ASSERTION_SEMANTIC_OBSERVE, \
|
||||||
|
_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE, \
|
||||||
|
_LIBCPP_ASSERTION_SEMANTIC_ENFORCE
|
||||||
|
|
||||||
|
# endif // _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_IGNORE
|
||||||
|
|
||||||
|
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
|
||||||
|
|
||||||
#endif // _LIBCPP___ASSERTION_HANDLER
|
#endif // _LIBCPP___ASSERTION_HANDLER
|
||||||
|
|||||||
Vendored
+36
-60
@@ -10,7 +10,9 @@
|
|||||||
#define _LIBCPP___ATOMIC_ATOMIC_H
|
#define _LIBCPP___ATOMIC_ATOMIC_H
|
||||||
|
|
||||||
#include <__atomic/atomic_sync.h>
|
#include <__atomic/atomic_sync.h>
|
||||||
|
#include <__atomic/atomic_waitable_traits.h>
|
||||||
#include <__atomic/check_memory_order.h>
|
#include <__atomic/check_memory_order.h>
|
||||||
|
#include <__atomic/floating_point_helper.h>
|
||||||
#include <__atomic/is_always_lock_free.h>
|
#include <__atomic/is_always_lock_free.h>
|
||||||
#include <__atomic/memory_order.h>
|
#include <__atomic/memory_order.h>
|
||||||
#include <__atomic/support.h>
|
#include <__atomic/support.h>
|
||||||
@@ -47,10 +49,10 @@ struct __atomic_base // false
|
|||||||
static constexpr bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value;
|
static constexpr bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI bool is_lock_free() const volatile _NOEXCEPT {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI 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 bool is_lock_free() const _NOEXCEPT {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI 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
|
||||||
@@ -61,11 +63,11 @@ struct __atomic_base // false
|
|||||||
_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
|
[[__nodiscard__]] _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
|
[[__nodiscard__]] _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);
|
||||||
}
|
}
|
||||||
@@ -113,22 +115,16 @@ struct __atomic_base // false
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 20
|
#if _LIBCPP_STD_VER >= 20
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const
|
_LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
|
||||||
volatile _NOEXCEPT {
|
|
||||||
std::__atomic_wait(*this, __v, __m);
|
std::__atomic_wait(*this, __v, __m);
|
||||||
}
|
}
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
_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::__atomic_wait(*this, __v, __m);
|
std::__atomic_wait(*this, __v, __m);
|
||||||
}
|
}
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
|
_LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { std::__atomic_notify_one(*this); }
|
||||||
std::__atomic_notify_one(*this);
|
_LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }
|
||||||
}
|
_LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { std::__atomic_notify_all(*this); }
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }
|
_LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
|
|
||||||
std::__atomic_notify_all(*this);
|
|
||||||
}
|
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 20
|
#if _LIBCPP_STD_VER >= 20
|
||||||
@@ -205,12 +201,15 @@ struct __atomic_base<_Tp, true> : public __atomic_base<_Tp, false> {
|
|||||||
_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_xor(__op) ^ __op; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if _LIBCPP_STD_VER >= 20
|
||||||
// Here we need _IsIntegral because the default template argument is not enough
|
// Here we need _IsIntegral because the default template argument is not enough
|
||||||
// e.g __atomic_base<int> is __atomic_base<int, true>, which inherits from
|
// e.g __atomic_base<int> is __atomic_base<int, true>, which inherits from
|
||||||
// __atomic_base<int, false> and the caller of the wait function is
|
// __atomic_base<int, false> and the caller of the wait function is
|
||||||
// __atomic_base<int, false>. So specializing __atomic_base<_Tp> does not work
|
// __atomic_base<int, false>. So specializing __atomic_base<_Tp> does not work
|
||||||
template <class _Tp, bool _IsIntegral>
|
template <class _Tp, bool _IsIntegral>
|
||||||
struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > {
|
struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > {
|
||||||
|
using __value_type _LIBCPP_NODEBUG = _Tp;
|
||||||
|
|
||||||
static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_base<_Tp, _IsIntegral>& __a, memory_order __order) {
|
static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_base<_Tp, _IsIntegral>& __a, memory_order __order) {
|
||||||
return __a.load(__order);
|
return __a.load(__order);
|
||||||
}
|
}
|
||||||
@@ -231,6 +230,8 @@ struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
template <typename _Tp>
|
template <typename _Tp>
|
||||||
struct __check_atomic_mandates {
|
struct __check_atomic_mandates {
|
||||||
using type _LIBCPP_NODEBUG = _Tp;
|
using type _LIBCPP_NODEBUG = _Tp;
|
||||||
@@ -324,50 +325,26 @@ struct atomic<_Tp*> : public __atomic_base<_Tp*> {
|
|||||||
atomic& operator=(const atomic&) volatile = delete;
|
atomic& operator=(const atomic&) volatile = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if _LIBCPP_STD_VER >= 20
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
struct __atomic_waitable_traits<atomic<_Tp> > : __atomic_waitable_traits<__atomic_base<_Tp> > {};
|
struct __atomic_waitable_traits<atomic<_Tp> > : __atomic_waitable_traits<__atomic_base<_Tp> > {};
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 20
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
requires is_floating_point_v<_Tp>
|
requires is_floating_point_v<_Tp>
|
||||||
struct atomic<_Tp> : __atomic_base<_Tp> {
|
struct atomic<_Tp> : __atomic_base<_Tp> {
|
||||||
private:
|
private:
|
||||||
_LIBCPP_HIDE_FROM_ABI static constexpr bool __is_fp80_long_double() {
|
|
||||||
// Only x87-fp80 long double has 64-bit mantissa
|
|
||||||
return __LDBL_MANT_DIG__ == 64 && std::is_same_v<_Tp, long double>;
|
|
||||||
}
|
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI static constexpr bool __has_rmw_builtin() {
|
|
||||||
# ifndef _LIBCPP_COMPILER_CLANG_BASED
|
|
||||||
return false;
|
|
||||||
# else
|
|
||||||
// The builtin __cxx_atomic_fetch_add errors during compilation for
|
|
||||||
// long double on platforms with fp80 format.
|
|
||||||
// For more details, see
|
|
||||||
// lib/Sema/SemaChecking.cpp function IsAllowedValueType
|
|
||||||
// LLVM Parser does not allow atomicrmw with x86_fp80 type.
|
|
||||||
// if (ValType->isSpecificBuiltinType(BuiltinType::LongDouble) &&
|
|
||||||
// &Context.getTargetInfo().getLongDoubleFormat() ==
|
|
||||||
// &llvm::APFloat::x87DoubleExtended())
|
|
||||||
// For more info
|
|
||||||
// https://github.com/llvm/llvm-project/issues/68602
|
|
||||||
// https://reviews.llvm.org/D53965
|
|
||||||
return !__is_fp80_long_double();
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class _This, class _Operation, class _BuiltinOp>
|
template <class _This, class _Operation, class _BuiltinOp>
|
||||||
_LIBCPP_HIDE_FROM_ABI static _Tp
|
_LIBCPP_HIDE_FROM_ABI static _Tp
|
||||||
__rmw_op(_This&& __self, _Tp __operand, memory_order __m, _Operation __operation, _BuiltinOp __builtin_op) {
|
__rmw_op(_This&& __self, _Tp __operand, memory_order __m, _Operation __operation, _BuiltinOp __builtin_op) {
|
||||||
if constexpr (__has_rmw_builtin()) {
|
if constexpr (std::__has_rmw_builtin<_Tp>()) {
|
||||||
return __builtin_op(std::addressof(std::forward<_This>(__self).__a_), __operand, __m);
|
return __builtin_op(std::addressof(std::forward<_This>(__self).__a_), __operand, __m);
|
||||||
} else {
|
} else {
|
||||||
_Tp __old = __self.load(memory_order_relaxed);
|
_Tp __old = __self.load(memory_order_relaxed);
|
||||||
_Tp __new = __operation(__old, __operand);
|
_Tp __new = __operation(__old, __operand);
|
||||||
while (!__self.compare_exchange_weak(__old, __new, __m, memory_order_relaxed)) {
|
while (!__self.compare_exchange_weak(__old, __new, __m, memory_order_relaxed)) {
|
||||||
# ifdef _LIBCPP_COMPILER_CLANG_BASED
|
# ifdef _LIBCPP_COMPILER_CLANG_BASED
|
||||||
if constexpr (__is_fp80_long_double()) {
|
if constexpr (std::__is_fp80_long_double<_Tp>()) {
|
||||||
// https://github.com/llvm/llvm-project/issues/47978
|
// https://llvm.org/PR47978
|
||||||
// clang bug: __old is not updated on failure for atomic<long double>::compare_exchange_weak
|
// clang bug: __old is not updated on failure for atomic<long double>::compare_exchange_weak
|
||||||
// Note __old = __self.load(memory_order_relaxed) will not work
|
// Note __old = __self.load(memory_order_relaxed) will not work
|
||||||
std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), std::addressof(__old), memory_order_relaxed);
|
std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), std::addressof(__old), memory_order_relaxed);
|
||||||
@@ -462,12 +439,12 @@ public:
|
|||||||
// atomic_is_lock_free
|
// atomic_is_lock_free
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT {
|
||||||
return __o->is_lock_free();
|
return __o->is_lock_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT {
|
||||||
return __o->is_lock_free();
|
return __o->is_lock_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,25 +493,25 @@ atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, me
|
|||||||
// atomic_load
|
// atomic_load
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT {
|
||||||
return __o->load();
|
return __o->load();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const atomic<_Tp>* __o) _NOEXCEPT {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const atomic<_Tp>* __o) _NOEXCEPT {
|
||||||
return __o->load();
|
return __o->load();
|
||||||
}
|
}
|
||||||
|
|
||||||
// atomic_load_explicit
|
// atomic_load_explicit
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp
|
||||||
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
|
atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
|
||||||
return __o->load(__m);
|
return __o->load(__m);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
|
||||||
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
|
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
|
||||||
return __o->load(__m);
|
return __o->load(__m);
|
||||||
}
|
}
|
||||||
@@ -642,28 +619,27 @@ _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit(
|
|||||||
// atomic_wait
|
// atomic_wait
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
_LIBCPP_HIDE_FROM_ABI void
|
||||||
atomic_wait(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT {
|
atomic_wait(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT {
|
||||||
return __o->wait(__v);
|
return __o->wait(__v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
_LIBCPP_HIDE_FROM_ABI void atomic_wait(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT {
|
||||||
atomic_wait(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT {
|
|
||||||
return __o->wait(__v);
|
return __o->wait(__v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// atomic_wait_explicit
|
// atomic_wait_explicit
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
_LIBCPP_HIDE_FROM_ABI void
|
||||||
atomic_wait_explicit(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT
|
atomic_wait_explicit(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT
|
||||||
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
|
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
|
||||||
return __o->wait(__v, __m);
|
return __o->wait(__v, __m);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
_LIBCPP_HIDE_FROM_ABI void
|
||||||
atomic_wait_explicit(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT
|
atomic_wait_explicit(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT
|
||||||
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
|
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
|
||||||
return __o->wait(__v, __m);
|
return __o->wait(__v, __m);
|
||||||
@@ -672,22 +648,22 @@ atomic_wait_explicit(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __
|
|||||||
// atomic_notify_one
|
// atomic_notify_one
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT {
|
_LIBCPP_HIDE_FROM_ABI void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT {
|
||||||
__o->notify_one();
|
__o->notify_one();
|
||||||
}
|
}
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT {
|
_LIBCPP_HIDE_FROM_ABI void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT {
|
||||||
__o->notify_one();
|
__o->notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
// atomic_notify_all
|
// atomic_notify_all
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT {
|
_LIBCPP_HIDE_FROM_ABI void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT {
|
||||||
__o->notify_all();
|
__o->notify_all();
|
||||||
}
|
}
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT {
|
_LIBCPP_HIDE_FROM_ABI void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT {
|
||||||
__o->notify_all();
|
__o->notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-37
@@ -10,6 +10,7 @@
|
|||||||
#define _LIBCPP___ATOMIC_ATOMIC_FLAG_H
|
#define _LIBCPP___ATOMIC_ATOMIC_FLAG_H
|
||||||
|
|
||||||
#include <__atomic/atomic_sync.h>
|
#include <__atomic/atomic_sync.h>
|
||||||
|
#include <__atomic/atomic_waitable_traits.h>
|
||||||
#include <__atomic/contention_t.h>
|
#include <__atomic/contention_t.h>
|
||||||
#include <__atomic/memory_order.h>
|
#include <__atomic/memory_order.h>
|
||||||
#include <__atomic/support.h>
|
#include <__atomic/support.h>
|
||||||
@@ -49,22 +50,16 @@ struct atomic_flag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 20
|
#if _LIBCPP_STD_VER >= 20
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const
|
_LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
|
||||||
volatile _NOEXCEPT {
|
|
||||||
std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
|
std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
|
||||||
}
|
}
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
_LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
|
||||||
wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
|
|
||||||
std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
|
std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
|
||||||
}
|
}
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
|
_LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { std::__atomic_notify_one(*this); }
|
||||||
std::__atomic_notify_one(*this);
|
_LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }
|
||||||
}
|
_LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { std::__atomic_notify_all(*this); }
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }
|
_LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
|
|
||||||
std::__atomic_notify_all(*this);
|
|
||||||
}
|
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 20
|
#if _LIBCPP_STD_VER >= 20
|
||||||
@@ -80,8 +75,11 @@ struct atomic_flag {
|
|||||||
atomic_flag& operator=(const atomic_flag&) volatile = delete;
|
atomic_flag& operator=(const atomic_flag&) volatile = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if _LIBCPP_STD_VER >= 20
|
||||||
template <>
|
template <>
|
||||||
struct __atomic_waitable_traits<atomic_flag> {
|
struct __atomic_waitable_traits<atomic_flag> {
|
||||||
|
using __value_type _LIBCPP_NODEBUG = _LIBCPP_ATOMIC_FLAG_TYPE;
|
||||||
|
|
||||||
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE __atomic_load(const atomic_flag& __a, memory_order __order) {
|
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE __atomic_load(const atomic_flag& __a, memory_order __order) {
|
||||||
return std::__cxx_atomic_load(&__a.__a_, __order);
|
return std::__cxx_atomic_load(&__a.__a_, __order);
|
||||||
}
|
}
|
||||||
@@ -101,6 +99,7 @@ struct __atomic_waitable_traits<atomic_flag> {
|
|||||||
return std::addressof(__a.__a_);
|
return std::addressof(__a.__a_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); }
|
inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); }
|
||||||
|
|
||||||
@@ -143,43 +142,26 @@ inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, m
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 20
|
#if _LIBCPP_STD_VER >= 20
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
|
inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT {
|
||||||
atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT {
|
|
||||||
__o->wait(__v);
|
__o->wait(__v);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
|
inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT { __o->wait(__v); }
|
||||||
atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT {
|
|
||||||
__o->wait(__v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
|
inline _LIBCPP_HIDE_FROM_ABI void
|
||||||
atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
|
atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
|
||||||
__o->wait(__v, __m);
|
__o->wait(__v, __m);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
|
inline _LIBCPP_HIDE_FROM_ABI void
|
||||||
atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
|
atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
|
||||||
__o->wait(__v, __m);
|
__o->wait(__v, __m);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
|
inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT { __o->notify_one(); }
|
||||||
atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT {
|
inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT { __o->notify_one(); }
|
||||||
__o->notify_one();
|
inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT { __o->notify_all(); }
|
||||||
}
|
inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT { __o->notify_all(); }
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|||||||
+29
-12
@@ -19,7 +19,9 @@
|
|||||||
|
|
||||||
#include <__assert>
|
#include <__assert>
|
||||||
#include <__atomic/atomic_sync.h>
|
#include <__atomic/atomic_sync.h>
|
||||||
|
#include <__atomic/atomic_waitable_traits.h>
|
||||||
#include <__atomic/check_memory_order.h>
|
#include <__atomic/check_memory_order.h>
|
||||||
|
#include <__atomic/floating_point_helper.h>
|
||||||
#include <__atomic/memory_order.h>
|
#include <__atomic/memory_order.h>
|
||||||
#include <__atomic/to_gcc_order.h>
|
#include <__atomic/to_gcc_order.h>
|
||||||
#include <__concepts/arithmetic.h>
|
#include <__concepts/arithmetic.h>
|
||||||
@@ -121,7 +123,9 @@ public:
|
|||||||
static constexpr bool is_always_lock_free =
|
static constexpr bool is_always_lock_free =
|
||||||
__atomic_always_lock_free(sizeof(_Tp), std::addressof(__get_aligner_instance<required_alignment>::__instance));
|
__atomic_always_lock_free(sizeof(_Tp), std::addressof(__get_aligner_instance<required_alignment>::__instance));
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI bool is_lock_free() const noexcept { return __atomic_is_lock_free(sizeof(_Tp), __ptr_); }
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const noexcept {
|
||||||
|
return __atomic_is_lock_free(sizeof(_Tp), __ptr_);
|
||||||
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI void store(_Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept
|
_LIBCPP_HIDE_FROM_ABI void store(_Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept
|
||||||
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__order) {
|
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__order) {
|
||||||
@@ -136,7 +140,7 @@ public:
|
|||||||
return __desired;
|
return __desired;
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __order = memory_order::seq_cst) const noexcept
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __order = memory_order::seq_cst) const noexcept
|
||||||
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__order) {
|
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__order) {
|
||||||
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
|
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
|
||||||
__order == memory_order::relaxed || __order == memory_order::consume || __order == memory_order::acquire ||
|
__order == memory_order::relaxed || __order == memory_order::consume || __order == memory_order::acquire ||
|
||||||
@@ -219,6 +223,9 @@ public:
|
|||||||
}
|
}
|
||||||
_LIBCPP_HIDE_FROM_ABI void notify_one() const noexcept { std::__atomic_notify_one(*this); }
|
_LIBCPP_HIDE_FROM_ABI void notify_one() const noexcept { std::__atomic_notify_one(*this); }
|
||||||
_LIBCPP_HIDE_FROM_ABI void notify_all() const noexcept { std::__atomic_notify_all(*this); }
|
_LIBCPP_HIDE_FROM_ABI void notify_all() const noexcept { std::__atomic_notify_all(*this); }
|
||||||
|
# if _LIBCPP_STD_VER >= 26
|
||||||
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp* address() const noexcept { return __ptr_; }
|
||||||
|
# endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using _Aligned_Tp [[__gnu__::__aligned__(required_alignment), __gnu__::__nodebug__]] = _Tp;
|
using _Aligned_Tp [[__gnu__::__aligned__(required_alignment), __gnu__::__nodebug__]] = _Tp;
|
||||||
@@ -229,6 +236,8 @@ protected:
|
|||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
struct __atomic_waitable_traits<__atomic_ref_base<_Tp>> {
|
struct __atomic_waitable_traits<__atomic_ref_base<_Tp>> {
|
||||||
|
using __value_type _LIBCPP_NODEBUG = _Tp;
|
||||||
|
|
||||||
static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_ref_base<_Tp>& __a, memory_order __order) {
|
static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_ref_base<_Tp>& __a, memory_order __order) {
|
||||||
return __a.load(__order);
|
return __a.load(__order);
|
||||||
}
|
}
|
||||||
@@ -322,20 +331,28 @@ struct atomic_ref<_Tp> : public __atomic_ref_base<_Tp> {
|
|||||||
atomic_ref& operator=(const atomic_ref&) = delete;
|
atomic_ref& operator=(const atomic_ref&) = delete;
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
|
_LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
|
||||||
_Tp __old = this->load(memory_order_relaxed);
|
if constexpr (std::__has_rmw_builtin<_Tp>()) {
|
||||||
_Tp __new = __old + __arg;
|
return __atomic_fetch_add(this->__ptr_, __arg, std::__to_gcc_order(__order));
|
||||||
while (!this->compare_exchange_weak(__old, __new, __order, memory_order_relaxed)) {
|
} else {
|
||||||
__new = __old + __arg;
|
_Tp __old = this->load(memory_order_relaxed);
|
||||||
|
_Tp __new = __old + __arg;
|
||||||
|
while (!this->compare_exchange_weak(__old, __new, __order, memory_order_relaxed)) {
|
||||||
|
__new = __old + __arg;
|
||||||
|
}
|
||||||
|
return __old;
|
||||||
}
|
}
|
||||||
return __old;
|
|
||||||
}
|
}
|
||||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
|
_LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
|
||||||
_Tp __old = this->load(memory_order_relaxed);
|
if constexpr (std::__has_rmw_builtin<_Tp>()) {
|
||||||
_Tp __new = __old - __arg;
|
return __atomic_fetch_sub(this->__ptr_, __arg, std::__to_gcc_order(__order));
|
||||||
while (!this->compare_exchange_weak(__old, __new, __order, memory_order_relaxed)) {
|
} else {
|
||||||
__new = __old - __arg;
|
_Tp __old = this->load(memory_order_relaxed);
|
||||||
|
_Tp __new = __old - __arg;
|
||||||
|
while (!this->compare_exchange_weak(__old, __new, __order, memory_order_relaxed)) {
|
||||||
|
__new = __old - __arg;
|
||||||
|
}
|
||||||
|
return __old;
|
||||||
}
|
}
|
||||||
return __old;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __arg) const noexcept { return fetch_add(__arg) + __arg; }
|
_LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __arg) const noexcept { return fetch_add(__arg) + __arg; }
|
||||||
|
|||||||
+126
-54
@@ -9,6 +9,7 @@
|
|||||||
#ifndef _LIBCPP___ATOMIC_ATOMIC_SYNC_H
|
#ifndef _LIBCPP___ATOMIC_ATOMIC_SYNC_H
|
||||||
#define _LIBCPP___ATOMIC_ATOMIC_SYNC_H
|
#define _LIBCPP___ATOMIC_ATOMIC_SYNC_H
|
||||||
|
|
||||||
|
#include <__atomic/atomic_waitable_traits.h>
|
||||||
#include <__atomic/contention_t.h>
|
#include <__atomic/contention_t.h>
|
||||||
#include <__atomic/memory_order.h>
|
#include <__atomic/memory_order.h>
|
||||||
#include <__atomic/to_gcc_order.h>
|
#include <__atomic/to_gcc_order.h>
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
#include <__type_traits/conjunction.h>
|
#include <__type_traits/conjunction.h>
|
||||||
#include <__type_traits/decay.h>
|
#include <__type_traits/decay.h>
|
||||||
#include <__type_traits/invoke.h>
|
#include <__type_traits/invoke.h>
|
||||||
|
#include <__type_traits/is_same.h>
|
||||||
#include <__type_traits/void_t.h>
|
#include <__type_traits/void_t.h>
|
||||||
#include <__utility/declval.h>
|
#include <__utility/declval.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@@ -29,50 +31,89 @@
|
|||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
// The customisation points to enable the following functions:
|
|
||||||
// - __atomic_wait
|
|
||||||
// - __atomic_wait_unless
|
|
||||||
// - __atomic_notify_one
|
|
||||||
// - __atomic_notify_all
|
|
||||||
// Note that std::atomic<T>::wait was back-ported to C++03
|
|
||||||
// The below implementations look ugly to support C++03
|
|
||||||
template <class _Tp, class = void>
|
|
||||||
struct __atomic_waitable_traits {
|
|
||||||
template <class _AtomicWaitable>
|
|
||||||
static void __atomic_load(_AtomicWaitable&&, memory_order) = delete;
|
|
||||||
|
|
||||||
template <class _AtomicWaitable>
|
|
||||||
static void __atomic_contention_address(_AtomicWaitable&&) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class _Tp, class = void>
|
|
||||||
struct __atomic_waitable : false_type {};
|
|
||||||
|
|
||||||
template <class _Tp>
|
|
||||||
struct __atomic_waitable< _Tp,
|
|
||||||
__void_t<decltype(__atomic_waitable_traits<__decay_t<_Tp> >::__atomic_load(
|
|
||||||
std::declval<const _Tp&>(), std::declval<memory_order>())),
|
|
||||||
decltype(__atomic_waitable_traits<__decay_t<_Tp> >::__atomic_contention_address(
|
|
||||||
std::declval<const _Tp&>()))> > : true_type {};
|
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 20
|
#if _LIBCPP_STD_VER >= 20
|
||||||
# if _LIBCPP_HAS_THREADS
|
# if _LIBCPP_HAS_THREADS
|
||||||
|
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*) _NOEXCEPT;
|
# if !_LIBCPP_AVAILABILITY_HAS_NEW_SYNC
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*) _NOEXCEPT;
|
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
|
|
||||||
__libcpp_atomic_monitor(void const volatile*) _NOEXCEPT;
|
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
|
|
||||||
__libcpp_atomic_wait(void const volatile*, __cxx_contention_t) _NOEXCEPT;
|
|
||||||
|
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
|
// old dylib interface kept for backwards compatibility
|
||||||
__cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
|
_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*) _NOEXCEPT;
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
|
_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*) _NOEXCEPT;
|
||||||
__cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
|
_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*) _NOEXCEPT;
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
|
_LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t) _NOEXCEPT;
|
||||||
|
|
||||||
|
_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
|
||||||
|
_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
|
||||||
|
_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
|
||||||
__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
|
__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
|
_LIBCPP_EXPORTED_FROM_ABI void
|
||||||
__libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t) _NOEXCEPT;
|
__libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t) _NOEXCEPT;
|
||||||
|
# endif // !_LIBCPP_AVAILABILITY_HAS_NEW_SYNC
|
||||||
|
|
||||||
|
// new dylib interface
|
||||||
|
|
||||||
|
// return the global contention state's current value for the address
|
||||||
|
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
|
||||||
|
__atomic_monitor_global(void const* __address) _NOEXCEPT;
|
||||||
|
|
||||||
|
// wait on the global contention state to be changed from the given value for the address
|
||||||
|
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void
|
||||||
|
__atomic_wait_global_table(void const* __address, __cxx_contention_t __monitor_value) _NOEXCEPT;
|
||||||
|
|
||||||
|
// notify one waiter waiting on the global contention state for the address
|
||||||
|
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_global_table(void const*) _NOEXCEPT;
|
||||||
|
|
||||||
|
// notify all waiters waiting on the global contention state for the address
|
||||||
|
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_global_table(void const*) _NOEXCEPT;
|
||||||
|
|
||||||
|
// wait on the address directly with the native platform wait
|
||||||
|
template <std::size_t _Size>
|
||||||
|
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void
|
||||||
|
__atomic_wait_native(void const* __address, void const* __old_value) _NOEXCEPT;
|
||||||
|
|
||||||
|
// notify one waiter waiting on the address directly with the native platform wait
|
||||||
|
template <std::size_t _Size>
|
||||||
|
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_native(const void*) _NOEXCEPT;
|
||||||
|
|
||||||
|
// notify all waiters waiting on the address directly with the native platform wait
|
||||||
|
template <std::size_t _Size>
|
||||||
|
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native(const void*) _NOEXCEPT;
|
||||||
|
|
||||||
|
# if _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
|
||||||
|
|
||||||
|
template <class _AtomicWaitable, class _Poll>
|
||||||
|
struct __atomic_wait_backoff_impl {
|
||||||
|
const _AtomicWaitable& __a_;
|
||||||
|
_Poll __poll_;
|
||||||
|
memory_order __order_;
|
||||||
|
|
||||||
|
using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
|
||||||
|
using __value_type _LIBCPP_NODEBUG = typename __waitable_traits::__value_type;
|
||||||
|
|
||||||
|
_LIBCPP_HIDE_FROM_ABI __backoff_results operator()(chrono::nanoseconds __elapsed) const {
|
||||||
|
if (__elapsed > chrono::microseconds(4)) {
|
||||||
|
auto __contention_address = const_cast<const void*>(
|
||||||
|
static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a_)));
|
||||||
|
|
||||||
|
if constexpr (__has_native_atomic_wait<__value_type>) {
|
||||||
|
auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_);
|
||||||
|
if (__poll_(__atomic_value))
|
||||||
|
return __backoff_results::__poll_success;
|
||||||
|
std::__atomic_wait_native<sizeof(__value_type)>(__contention_address, std::addressof(__atomic_value));
|
||||||
|
} else {
|
||||||
|
__cxx_contention_t __monitor_val = std::__atomic_monitor_global(__contention_address);
|
||||||
|
auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_);
|
||||||
|
if (__poll_(__atomic_value))
|
||||||
|
return __backoff_results::__poll_success;
|
||||||
|
std::__atomic_wait_global_table(__contention_address, __monitor_val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
} // poll
|
||||||
|
return __backoff_results::__continue_poll;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
# else // _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
|
||||||
|
|
||||||
template <class _AtomicWaitable, class _Poll>
|
template <class _AtomicWaitable, class _Poll>
|
||||||
struct __atomic_wait_backoff_impl {
|
struct __atomic_wait_backoff_impl {
|
||||||
@@ -82,7 +123,6 @@ struct __atomic_wait_backoff_impl {
|
|||||||
|
|
||||||
using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
|
using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
|
||||||
|
|
||||||
_LIBCPP_AVAILABILITY_SYNC
|
|
||||||
_LIBCPP_HIDE_FROM_ABI bool
|
_LIBCPP_HIDE_FROM_ABI bool
|
||||||
__update_monitor_val_and_poll(__cxx_atomic_contention_t const volatile*, __cxx_contention_t& __monitor_val) const {
|
__update_monitor_val_and_poll(__cxx_atomic_contention_t const volatile*, __cxx_contention_t& __monitor_val) const {
|
||||||
// In case the contention type happens to be __cxx_atomic_contention_t, i.e. __cxx_atomic_impl<int64_t>,
|
// In case the contention type happens to be __cxx_atomic_contention_t, i.e. __cxx_atomic_impl<int64_t>,
|
||||||
@@ -95,7 +135,6 @@ struct __atomic_wait_backoff_impl {
|
|||||||
return __poll_(__monitor_val);
|
return __poll_(__monitor_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_AVAILABILITY_SYNC
|
|
||||||
_LIBCPP_HIDE_FROM_ABI bool
|
_LIBCPP_HIDE_FROM_ABI bool
|
||||||
__update_monitor_val_and_poll(void const volatile* __contention_address, __cxx_contention_t& __monitor_val) const {
|
__update_monitor_val_and_poll(void const volatile* __contention_address, __cxx_contention_t& __monitor_val) const {
|
||||||
// In case the contention type is anything else, platform wait is monitoring a __cxx_atomic_contention_t
|
// In case the contention type is anything else, platform wait is monitoring a __cxx_atomic_contention_t
|
||||||
@@ -105,20 +144,21 @@ struct __atomic_wait_backoff_impl {
|
|||||||
return __poll_(__current_val);
|
return __poll_(__current_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_AVAILABILITY_SYNC
|
_LIBCPP_HIDE_FROM_ABI __backoff_results operator()(chrono::nanoseconds __elapsed) const {
|
||||||
_LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const {
|
|
||||||
if (__elapsed > chrono::microseconds(4)) {
|
if (__elapsed > chrono::microseconds(4)) {
|
||||||
auto __contention_address = __waitable_traits::__atomic_contention_address(__a_);
|
auto __contention_address = __waitable_traits::__atomic_contention_address(__a_);
|
||||||
__cxx_contention_t __monitor_val;
|
__cxx_contention_t __monitor_val;
|
||||||
if (__update_monitor_val_and_poll(__contention_address, __monitor_val))
|
if (__update_monitor_val_and_poll(__contention_address, __monitor_val))
|
||||||
return true;
|
return __backoff_results::__poll_success;
|
||||||
std::__libcpp_atomic_wait(__contention_address, __monitor_val);
|
std::__libcpp_atomic_wait(__contention_address, __monitor_val);
|
||||||
} else {
|
} else {
|
||||||
} // poll
|
} // poll
|
||||||
return false;
|
return __backoff_results::__continue_poll;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# endif // _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
|
||||||
|
|
||||||
// The semantics of this function are similar to `atomic`'s
|
// The semantics of this function are similar to `atomic`'s
|
||||||
// `.wait(T old, std::memory_order order)`, but instead of having a hardcoded
|
// `.wait(T old, std::memory_order order)`, but instead of having a hardcoded
|
||||||
// predicate (is the loaded value unequal to `old`?), the predicate function is
|
// predicate (is the loaded value unequal to `old`?), the predicate function is
|
||||||
@@ -128,9 +168,8 @@ struct __atomic_wait_backoff_impl {
|
|||||||
// `false`, it must set the argument to its current understanding of the atomic
|
// `false`, it must set the argument to its current understanding of the atomic
|
||||||
// value. The predicate function must not return `false` spuriously.
|
// value. The predicate function must not return `false` spuriously.
|
||||||
template <class _AtomicWaitable, class _Poll>
|
template <class _AtomicWaitable, class _Poll>
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
_LIBCPP_HIDE_FROM_ABI void __atomic_wait_unless(const _AtomicWaitable& __a, memory_order __order, _Poll&& __poll) {
|
||||||
__atomic_wait_unless(const _AtomicWaitable& __a, memory_order __order, _Poll&& __poll) {
|
static_assert(__atomic_waitable<_AtomicWaitable>);
|
||||||
static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
|
|
||||||
__atomic_wait_backoff_impl<_AtomicWaitable, __decay_t<_Poll> > __backoff_fn = {__a, __poll, __order};
|
__atomic_wait_backoff_impl<_AtomicWaitable, __decay_t<_Poll> > __backoff_fn = {__a, __poll, __order};
|
||||||
std::__libcpp_thread_poll_with_backoff(
|
std::__libcpp_thread_poll_with_backoff(
|
||||||
/* poll */
|
/* poll */
|
||||||
@@ -141,18 +180,52 @@ __atomic_wait_unless(const _AtomicWaitable& __a, memory_order __order, _Poll&& _
|
|||||||
/* backoff */ __backoff_fn);
|
/* backoff */ __backoff_fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
|
||||||
|
|
||||||
template <class _AtomicWaitable>
|
template <class _AtomicWaitable>
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable& __a) {
|
_LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable& __a) {
|
||||||
static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
|
static_assert(__atomic_waitable<_AtomicWaitable>);
|
||||||
|
using __value_type _LIBCPP_NODEBUG = typename __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__value_type;
|
||||||
|
using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
|
||||||
|
auto __contention_address =
|
||||||
|
const_cast<const void*>(static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a)));
|
||||||
|
if constexpr (__has_native_atomic_wait<__value_type>) {
|
||||||
|
std::__atomic_notify_one_native<sizeof(__value_type)>(__contention_address);
|
||||||
|
} else {
|
||||||
|
std::__atomic_notify_one_global_table(__contention_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _AtomicWaitable>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable& __a) {
|
||||||
|
static_assert(__atomic_waitable<_AtomicWaitable>);
|
||||||
|
using __value_type _LIBCPP_NODEBUG = typename __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__value_type;
|
||||||
|
using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
|
||||||
|
auto __contention_address =
|
||||||
|
const_cast<const void*>(static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a)));
|
||||||
|
if constexpr (__has_native_atomic_wait<__value_type>) {
|
||||||
|
std::__atomic_notify_all_native<sizeof(__value_type)>(__contention_address);
|
||||||
|
} else {
|
||||||
|
std::__atomic_notify_all_global_table(__contention_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# else // _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
|
||||||
|
|
||||||
|
template <class _AtomicWaitable>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable& __a) {
|
||||||
|
static_assert(__atomic_waitable<_AtomicWaitable>);
|
||||||
std::__cxx_atomic_notify_one(__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a));
|
std::__cxx_atomic_notify_one(__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _AtomicWaitable>
|
template <class _AtomicWaitable>
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable& __a) {
|
_LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable& __a) {
|
||||||
static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
|
static_assert(__atomic_waitable<_AtomicWaitable>);
|
||||||
std::__cxx_atomic_notify_all(__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a));
|
std::__cxx_atomic_notify_all(__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
# else // _LIBCPP_HAS_THREADS
|
# else // _LIBCPP_HAS_THREADS
|
||||||
|
|
||||||
template <class _AtomicWaitable, class _Poll>
|
template <class _AtomicWaitable, class _Poll>
|
||||||
@@ -180,9 +253,8 @@ _LIBCPP_HIDE_FROM_ABI bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp c
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class _AtomicWaitable, class _Tp>
|
template <class _AtomicWaitable, class _Tp>
|
||||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
_LIBCPP_HIDE_FROM_ABI void __atomic_wait(_AtomicWaitable& __a, _Tp __val, memory_order __order) {
|
||||||
__atomic_wait(_AtomicWaitable& __a, _Tp __val, memory_order __order) {
|
static_assert(__atomic_waitable<_AtomicWaitable>);
|
||||||
static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
|
|
||||||
std::__atomic_wait_unless(__a, __order, [&](_Tp const& __current) {
|
std::__atomic_wait_unless(__a, __order, [&](_Tp const& __current) {
|
||||||
return !std::__cxx_nonatomic_compare_equal(__current, __val);
|
return !std::__cxx_nonatomic_compare_equal(__current, __val);
|
||||||
});
|
});
|
||||||
|
|||||||
+144
@@ -0,0 +1,144 @@
|
|||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef _LIBCPP___ATOMIC_ATOMIC_SYNC_TIMED_H
|
||||||
|
#define _LIBCPP___ATOMIC_ATOMIC_SYNC_TIMED_H
|
||||||
|
|
||||||
|
#include <__atomic/atomic_waitable_traits.h>
|
||||||
|
#include <__atomic/contention_t.h>
|
||||||
|
#include <__atomic/memory_order.h>
|
||||||
|
#include <__atomic/to_gcc_order.h>
|
||||||
|
#include <__chrono/duration.h>
|
||||||
|
#include <__config>
|
||||||
|
#include <__memory/addressof.h>
|
||||||
|
#include <__thread/poll_with_backoff.h>
|
||||||
|
#include <__thread/timed_backoff_policy.h>
|
||||||
|
#include <__type_traits/conjunction.h>
|
||||||
|
#include <__type_traits/decay.h>
|
||||||
|
#include <__type_traits/has_unique_object_representation.h>
|
||||||
|
#include <__type_traits/invoke.h>
|
||||||
|
#include <__type_traits/is_same.h>
|
||||||
|
#include <__type_traits/is_trivially_copyable.h>
|
||||||
|
#include <__type_traits/void_t.h>
|
||||||
|
#include <__utility/declval.h>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
|
# pragma GCC system_header
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
|
#if _LIBCPP_STD_VER >= 20
|
||||||
|
# if _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
|
||||||
|
|
||||||
|
_LIBCPP_AVAILABILITY_NEW_SYNC
|
||||||
|
_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __atomic_monitor_global(void const* __address) _NOEXCEPT;
|
||||||
|
|
||||||
|
// wait on the global contention state to be changed from the given value for the address
|
||||||
|
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_global_table_with_timeout(
|
||||||
|
void const* __address, __cxx_contention_t __monitor_value, uint64_t __timeout_ns) _NOEXCEPT;
|
||||||
|
|
||||||
|
// wait on the address directly with the native platform wait
|
||||||
|
template <std::size_t _Size>
|
||||||
|
_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void
|
||||||
|
__atomic_wait_native_with_timeout(void const* __address, void const* __old_value, uint64_t __timeout_ns) _NOEXCEPT;
|
||||||
|
|
||||||
|
template <class _AtomicWaitable, class _Poll, class _Rep, class _Period>
|
||||||
|
struct __atomic_wait_timed_backoff_impl {
|
||||||
|
const _AtomicWaitable& __a_;
|
||||||
|
_Poll __poll_;
|
||||||
|
memory_order __order_;
|
||||||
|
chrono::duration<_Rep, _Period> __rel_time_;
|
||||||
|
|
||||||
|
using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
|
||||||
|
using __value_type _LIBCPP_NODEBUG = typename __waitable_traits::__value_type;
|
||||||
|
|
||||||
|
_LIBCPP_HIDE_FROM_ABI __backoff_results operator()(chrono::nanoseconds __elapsed) const {
|
||||||
|
if (__elapsed > chrono::microseconds(4)) {
|
||||||
|
auto __contention_address = const_cast<const void*>(
|
||||||
|
static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a_)));
|
||||||
|
|
||||||
|
uint64_t __timeout_ns =
|
||||||
|
static_cast<uint64_t>((chrono::duration_cast<chrono::nanoseconds>(__rel_time_) - __elapsed).count());
|
||||||
|
|
||||||
|
if constexpr (__has_native_atomic_wait<__value_type>) {
|
||||||
|
auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_);
|
||||||
|
if (__poll_(__atomic_value))
|
||||||
|
return __backoff_results::__poll_success;
|
||||||
|
std::__atomic_wait_native_with_timeout<sizeof(__value_type)>(
|
||||||
|
__contention_address, std::addressof(__atomic_value), __timeout_ns);
|
||||||
|
} else {
|
||||||
|
__cxx_contention_t __monitor_val = std::__atomic_monitor_global(__contention_address);
|
||||||
|
auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_);
|
||||||
|
if (__poll_(__atomic_value))
|
||||||
|
return __backoff_results::__poll_success;
|
||||||
|
std::__atomic_wait_global_table_with_timeout(__contention_address, __monitor_val, __timeout_ns);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
} // poll
|
||||||
|
return __backoff_results::__continue_poll;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The semantics of this function are similar to `atomic`'s
|
||||||
|
// `.wait(T old, std::memory_order order)` with a timeout, but instead of having a hardcoded
|
||||||
|
// predicate (is the loaded value unequal to `old`?), the predicate function is
|
||||||
|
// specified as an argument. The loaded value is given as an in-out argument to
|
||||||
|
// the predicate. If the predicate function returns `true`,
|
||||||
|
// `__atomic_wait_unless_with_timeout` will return. If the predicate function returns
|
||||||
|
// `false`, it must set the argument to its current understanding of the atomic
|
||||||
|
// value. The predicate function must not return `false` spuriously.
|
||||||
|
template <class _AtomicWaitable, class _Poll, class _Rep, class _Period>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI bool __atomic_wait_unless_with_timeout(
|
||||||
|
const _AtomicWaitable& __a,
|
||||||
|
memory_order __order,
|
||||||
|
_Poll&& __poll,
|
||||||
|
chrono::duration<_Rep, _Period> const& __rel_time) {
|
||||||
|
static_assert(__atomic_waitable<_AtomicWaitable>, "");
|
||||||
|
__atomic_wait_timed_backoff_impl<_AtomicWaitable, __decay_t<_Poll>, _Rep, _Period> __backoff_fn = {
|
||||||
|
__a, __poll, __order, __rel_time};
|
||||||
|
auto __poll_result = std::__libcpp_thread_poll_with_backoff(
|
||||||
|
/* poll */
|
||||||
|
[&]() {
|
||||||
|
auto __current_val = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_load(__a, __order);
|
||||||
|
return __poll(__current_val);
|
||||||
|
},
|
||||||
|
/* backoff */ __backoff_fn,
|
||||||
|
__rel_time);
|
||||||
|
|
||||||
|
return __poll_result == __poll_with_backoff_results::__poll_success;
|
||||||
|
}
|
||||||
|
|
||||||
|
# elif _LIBCPP_HAS_THREADS // _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
|
||||||
|
|
||||||
|
template <class _AtomicWaitable, class _Poll, class _Rep, class _Period>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI bool __atomic_wait_unless_with_timeout(
|
||||||
|
const _AtomicWaitable& __a,
|
||||||
|
memory_order __order,
|
||||||
|
_Poll&& __poll,
|
||||||
|
chrono::duration<_Rep, _Period> const& __rel_time) {
|
||||||
|
auto __res = std::__libcpp_thread_poll_with_backoff(
|
||||||
|
/* poll */
|
||||||
|
[&]() {
|
||||||
|
auto __current_val = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_load(__a, __order);
|
||||||
|
return __poll(__current_val);
|
||||||
|
},
|
||||||
|
/* backoff */ __libcpp_timed_backoff_policy(),
|
||||||
|
__rel_time);
|
||||||
|
return __res == __poll_with_backoff_results::__poll_success;
|
||||||
|
}
|
||||||
|
|
||||||
|
# endif // _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_NEW_SYNC
|
||||||
|
|
||||||
|
#endif // C++20
|
||||||
|
|
||||||
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
|
#endif // _LIBCPP___ATOMIC_ATOMIC_SYNC_TIMED_H
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef _LIBCPP___ATOMIC_ATOMIC_WAITABLE_TRAITS_H
|
||||||
|
#define _LIBCPP___ATOMIC_ATOMIC_WAITABLE_TRAITS_H
|
||||||
|
|
||||||
|
#include <__atomic/contention_t.h>
|
||||||
|
#include <__atomic/memory_order.h>
|
||||||
|
#include <__config>
|
||||||
|
#include <__type_traits/decay.h>
|
||||||
|
#include <__type_traits/has_unique_object_representation.h>
|
||||||
|
#include <__type_traits/is_same.h>
|
||||||
|
#include <__type_traits/is_trivially_copyable.h>
|
||||||
|
#include <__type_traits/void_t.h>
|
||||||
|
#include <__utility/declval.h>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
|
# pragma GCC system_header
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
|
#if _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
|
// The customisation points to enable the following functions:
|
||||||
|
// - __atomic_wait
|
||||||
|
// - __atomic_wait_unless
|
||||||
|
// - __atomic_notify_one
|
||||||
|
// - __atomic_notify_all
|
||||||
|
template <class _Tp, class = void>
|
||||||
|
struct __atomic_waitable_traits {
|
||||||
|
using __value_type _LIBCPP_NODEBUG = void;
|
||||||
|
|
||||||
|
template <class _AtomicWaitable>
|
||||||
|
static void __atomic_load(_AtomicWaitable&&, memory_order) = delete;
|
||||||
|
|
||||||
|
template <class _AtomicWaitable>
|
||||||
|
static void __atomic_contention_address(_AtomicWaitable&&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Tp>
|
||||||
|
concept __atomic_waitable = requires(const _Tp __t, memory_order __order) {
|
||||||
|
typename __atomic_waitable_traits<__decay_t<_Tp> >::__value_type;
|
||||||
|
{ __atomic_waitable_traits<__decay_t<_Tp> >::__atomic_load(__t, __order) };
|
||||||
|
{ __atomic_waitable_traits<__decay_t<_Tp> >::__atomic_contention_address(__t) };
|
||||||
|
};
|
||||||
|
|
||||||
|
# ifdef __linux__
|
||||||
|
# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(4)
|
||||||
|
# elif defined(__APPLE__)
|
||||||
|
# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) \
|
||||||
|
_APPLY(4) \
|
||||||
|
_APPLY(8)
|
||||||
|
# elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
|
||||||
|
# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(8)
|
||||||
|
# elif defined(_WIN32)
|
||||||
|
# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(8)
|
||||||
|
# else
|
||||||
|
# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(sizeof(__cxx_contention_t))
|
||||||
|
# endif // __linux__
|
||||||
|
|
||||||
|
// concepts defines the types are supported natively by the platform's wait
|
||||||
|
|
||||||
|
# if defined(_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE)
|
||||||
|
|
||||||
|
template <class _Tp>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI constexpr bool __has_native_atomic_wait_impl() {
|
||||||
|
if (alignof(_Tp) % sizeof(_Tp) != 0)
|
||||||
|
return false;
|
||||||
|
switch (sizeof(_Tp)) {
|
||||||
|
# define _LIBCPP_MAKE_CASE(n) \
|
||||||
|
case n: \
|
||||||
|
return true;
|
||||||
|
_LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_LIBCPP_MAKE_CASE)
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
# undef _LIBCPP_MAKE_CASE
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _Tp>
|
||||||
|
concept __has_native_atomic_wait =
|
||||||
|
has_unique_object_representations_v<_Tp> && is_trivially_copyable_v<_Tp> &&
|
||||||
|
std::__has_native_atomic_wait_impl<_Tp>();
|
||||||
|
|
||||||
|
# else // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
|
||||||
|
|
||||||
|
template <class _Tp>
|
||||||
|
concept __has_native_atomic_wait = is_same_v<_Tp, __cxx_contention_t>;
|
||||||
|
|
||||||
|
# endif // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
|
||||||
|
|
||||||
|
#endif // C++20
|
||||||
|
|
||||||
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
|
#endif // _LIBCPP___ATOMIC_ATOMIC_WAITABLE_TRAITS_H
|
||||||
+27
-3
@@ -19,11 +19,35 @@
|
|||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
|
// The original definition of `__cxx_contention_t` seemed a bit arbitrary.
|
||||||
|
// When we enable the _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE ABI,
|
||||||
|
// use definitions that are based on what the underlying platform supports
|
||||||
|
// instead.
|
||||||
|
#if defined(_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE)
|
||||||
|
|
||||||
|
# ifdef __linux__
|
||||||
using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
|
using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
|
||||||
#else
|
# elif defined(__APPLE__)
|
||||||
using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
|
using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
|
||||||
#endif // __linux__ || (_AIX && !__64BIT__)
|
# elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
|
||||||
|
using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
|
||||||
|
# elif defined(_AIX) && !defined(__64BIT__)
|
||||||
|
using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
|
||||||
|
# elif defined(_WIN32)
|
||||||
|
using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
|
||||||
|
# else
|
||||||
|
using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
|
||||||
|
# endif // __linux__
|
||||||
|
|
||||||
|
#else // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
|
||||||
|
|
||||||
|
# if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
|
||||||
|
using __cxx_contention_t _LIBCPP_NODEBUG = int32_t;
|
||||||
|
# else
|
||||||
|
using __cxx_contention_t _LIBCPP_NODEBUG = int64_t;
|
||||||
|
# endif // __linux__ || (_AIX && !__64BIT__)
|
||||||
|
|
||||||
|
#endif // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
|
||||||
|
|
||||||
using __cxx_atomic_contention_t _LIBCPP_NODEBUG = __cxx_atomic_impl<__cxx_contention_t>;
|
using __cxx_atomic_contention_t _LIBCPP_NODEBUG = __cxx_atomic_impl<__cxx_contention_t>;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef _LIBCPP___ATOMIC_FLOATING_POINT_HELPER_H
|
||||||
|
#define _LIBCPP___ATOMIC_FLOATING_POINT_HELPER_H
|
||||||
|
|
||||||
|
#include <__config>
|
||||||
|
#include <__type_traits/is_floating_point.h>
|
||||||
|
#include <__type_traits/is_same.h>
|
||||||
|
|
||||||
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
|
# pragma GCC system_header
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
|
#if _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
|
template <class _Tp>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI constexpr bool __is_fp80_long_double() {
|
||||||
|
// Only x87-fp80 long double has 64-bit mantissa
|
||||||
|
return __LDBL_MANT_DIG__ == 64 && std::is_same_v<_Tp, long double>;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _Tp>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI constexpr bool __has_rmw_builtin() {
|
||||||
|
static_assert(std::is_floating_point_v<_Tp>);
|
||||||
|
# ifndef _LIBCPP_COMPILER_CLANG_BASED
|
||||||
|
return false;
|
||||||
|
# else
|
||||||
|
// The builtin __cxx_atomic_fetch_add errors during compilation for
|
||||||
|
// long double on platforms with fp80 format.
|
||||||
|
// For more details, see
|
||||||
|
// lib/Sema/SemaChecking.cpp function IsAllowedValueType
|
||||||
|
// LLVM Parser does not allow atomicrmw with x86_fp80 type.
|
||||||
|
// if (ValType->isSpecificBuiltinType(BuiltinType::LongDouble) &&
|
||||||
|
// &Context.getTargetInfo().getLongDoubleFormat() ==
|
||||||
|
// &llvm::APFloat::x87DoubleExtended())
|
||||||
|
// For more info
|
||||||
|
// https://llvm.org/PR68602
|
||||||
|
// https://reviews.llvm.org/D53965
|
||||||
|
return !std::__is_fp80_long_double<_Tp>();
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
|
#endif // _LIBCPP___ATOMIC_FLOATING_POINT_HELPER_H
|
||||||
Vendored
+1
-2
@@ -24,7 +24,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countl_zero(_Tp __t) _NOEXCEPT {
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countl_zero(_Tp __t) _NOEXCEPT {
|
||||||
static_assert(__is_unsigned_integer_v<_Tp>, "__countl_zero requires an unsigned integer type");
|
|
||||||
return __builtin_clzg(__t, numeric_limits<_Tp>::digits);
|
return __builtin_clzg(__t, numeric_limits<_Tp>::digits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +36,7 @@ template <__unsigned_integer _Tp>
|
|||||||
|
|
||||||
template <__unsigned_integer _Tp>
|
template <__unsigned_integer _Tp>
|
||||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept {
|
||||||
return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
|
return std::countl_zero(static_cast<_Tp>(~__t));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
Vendored
+1
-2
@@ -24,7 +24,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __countr_zero(_Tp __t) _NOEXCEPT {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __countr_zero(_Tp __t) _NOEXCEPT {
|
||||||
static_assert(__is_unsigned_integer_v<_Tp>, "__countr_zero only works with unsigned types");
|
|
||||||
return __builtin_ctzg(__t, numeric_limits<_Tp>::digits);
|
return __builtin_ctzg(__t, numeric_limits<_Tp>::digits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +36,7 @@ template <__unsigned_integer _Tp>
|
|||||||
|
|
||||||
template <__unsigned_integer _Tp>
|
template <__unsigned_integer _Tp>
|
||||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {
|
||||||
return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
|
return std::countr_zero(static_cast<_Tp>(~__t));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
|
|
||||||
template <__unsigned_integer _Tp>
|
template <__unsigned_integer _Tp>
|
||||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
|
||||||
return __t != 0 && (((__t & (__t - 1)) == 0));
|
return __builtin_popcountg(__t) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|||||||
Vendored
-1
@@ -23,7 +23,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __popcount(_Tp __t) _NOEXCEPT {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __popcount(_Tp __t) _NOEXCEPT {
|
||||||
static_assert(__is_unsigned_integer_v<_Tp>, "__popcount only works with unsigned types");
|
|
||||||
return __builtin_popcountg(__t);
|
return __builtin_popcountg(__t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+20
-31
@@ -22,46 +22,35 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
// Writing two full functions for rotl and rotr makes it easier for the compiler
|
// Writing two full functions for rotl and rotr makes it easier for the compiler
|
||||||
// to optimize the code. On x86 this function becomes the ROL instruction and
|
// to optimize the code. On x86 this function becomes the ROL instruction and
|
||||||
// the rotr function becomes the ROR instruction.
|
// the rotr function becomes the ROR instruction.
|
||||||
template <class _Tp>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotl(_Tp __x, int __s) _NOEXCEPT {
|
|
||||||
static_assert(__is_unsigned_integer_v<_Tp>, "__rotl requires an unsigned integer type");
|
|
||||||
const int __n = numeric_limits<_Tp>::digits;
|
|
||||||
int __r = __s % __n;
|
|
||||||
|
|
||||||
if (__r == 0)
|
|
||||||
return __x;
|
|
||||||
|
|
||||||
if (__r > 0)
|
|
||||||
return (__x << __r) | (__x >> (__n - __r));
|
|
||||||
|
|
||||||
return (__x >> -__r) | (__x << (__n + __r));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class _Tp>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotr(_Tp __x, int __s) _NOEXCEPT {
|
|
||||||
static_assert(__is_unsigned_integer_v<_Tp>, "__rotr requires an unsigned integer type");
|
|
||||||
const int __n = numeric_limits<_Tp>::digits;
|
|
||||||
int __r = __s % __n;
|
|
||||||
|
|
||||||
if (__r == 0)
|
|
||||||
return __x;
|
|
||||||
|
|
||||||
if (__r > 0)
|
|
||||||
return (__x >> __r) | (__x << (__n - __r));
|
|
||||||
|
|
||||||
return (__x << -__r) | (__x >> (__n + __r));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 20
|
#if _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
template <__unsigned_integer _Tp>
|
template <__unsigned_integer _Tp>
|
||||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, int __cnt) noexcept {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, int __cnt) noexcept {
|
||||||
return std::__rotl(__t, __cnt);
|
const int __n = numeric_limits<_Tp>::digits;
|
||||||
|
int __r = __cnt % __n;
|
||||||
|
|
||||||
|
if (__r == 0)
|
||||||
|
return __t;
|
||||||
|
|
||||||
|
if (__r > 0)
|
||||||
|
return (__t << __r) | (__t >> (__n - __r));
|
||||||
|
|
||||||
|
return (__t >> -__r) | (__t << (__n + __r));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <__unsigned_integer _Tp>
|
template <__unsigned_integer _Tp>
|
||||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, int __cnt) noexcept {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, int __cnt) noexcept {
|
||||||
return std::__rotr(__t, __cnt);
|
const int __n = numeric_limits<_Tp>::digits;
|
||||||
|
int __r = __cnt % __n;
|
||||||
|
|
||||||
|
if (__r == 0)
|
||||||
|
return __t;
|
||||||
|
|
||||||
|
if (__r > 0)
|
||||||
|
return (__t >> __r) | (__t << (__n - __r));
|
||||||
|
|
||||||
|
return (__t << -__r) | (__t >> (__n + __r));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
Vendored
+207
-18
@@ -15,8 +15,10 @@
|
|||||||
#include <__algorithm/copy_backward.h>
|
#include <__algorithm/copy_backward.h>
|
||||||
#include <__algorithm/copy_n.h>
|
#include <__algorithm/copy_n.h>
|
||||||
#include <__algorithm/equal.h>
|
#include <__algorithm/equal.h>
|
||||||
|
#include <__algorithm/fill_n.h>
|
||||||
#include <__algorithm/min.h>
|
#include <__algorithm/min.h>
|
||||||
#include <__algorithm/rotate.h>
|
#include <__algorithm/rotate.h>
|
||||||
|
#include <__algorithm/specialized_algorithms.h>
|
||||||
#include <__algorithm/swap_ranges.h>
|
#include <__algorithm/swap_ranges.h>
|
||||||
#include <__assert>
|
#include <__assert>
|
||||||
#include <__bit/countr.h>
|
#include <__bit/countr.h>
|
||||||
@@ -137,7 +139,7 @@ public:
|
|||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT {
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT {
|
||||||
return static_cast<bool>(*__seg_ & __mask_);
|
return static_cast<bool>(*__seg_ & __mask_);
|
||||||
}
|
}
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT {
|
||||||
return !static_cast<bool>(*this);
|
return !static_cast<bool>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,6 +309,15 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR
|
||||||
|
template <bool _IsConstDep = _IsConst, __enable_if_t<_IsConstDep, int> = 0>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
|
||||||
|
: __seg_(__it.__seg_),
|
||||||
|
__ctz_(__it.__ctz_) {}
|
||||||
|
|
||||||
|
_LIBCPP_HIDE_FROM_ABI __bit_iterator(const __bit_iterator&) = default;
|
||||||
|
_LIBCPP_HIDE_FROM_ABI __bit_iterator& operator=(const __bit_iterator&) = default;
|
||||||
|
#else
|
||||||
// When _IsConst=false, this is the copy constructor.
|
// When _IsConst=false, this is the copy constructor.
|
||||||
// It is non-trivial. Making it trivial would break ABI.
|
// It is non-trivial. Making it trivial would break ABI.
|
||||||
// When _IsConst=true, this is a converting constructor;
|
// When _IsConst=true, this is a converting constructor;
|
||||||
@@ -327,6 +338,7 @@ public:
|
|||||||
__ctz_ = __it.__ctz_;
|
__ctz_ = __it.__ctz_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT {
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT {
|
||||||
_LIBCPP_ASSERT_INTERNAL(__ctz_ < __bits_per_word, "Dereferencing an invalid __bit_iterator.");
|
_LIBCPP_ASSERT_INTERNAL(__ctz_ < __bits_per_word, "Dereferencing an invalid __bit_iterator.");
|
||||||
@@ -467,20 +479,6 @@ private:
|
|||||||
template <class _Dp>
|
template <class _Dp>
|
||||||
friend struct __bit_array;
|
friend struct __bit_array;
|
||||||
|
|
||||||
template <bool _FillVal, class _Dp>
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 friend void
|
|
||||||
__fill_n_bool(__bit_iterator<_Dp, false> __first, typename __size_difference_type_traits<_Dp>::size_type __n);
|
|
||||||
|
|
||||||
template <class _Dp, bool _IC>
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_aligned(
|
|
||||||
__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
|
|
||||||
template <class _Dp, bool _IC>
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_unaligned(
|
|
||||||
__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
|
|
||||||
template <class _Dp, bool _IC>
|
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 friend pair<__bit_iterator<_Dp, _IC>, __bit_iterator<_Dp, false> >
|
|
||||||
__copy_impl::operator()(
|
|
||||||
__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result) const;
|
|
||||||
template <class _Dp, bool _IC>
|
template <class _Dp, bool _IC>
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_aligned(
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_aligned(
|
||||||
__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
|
__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
|
||||||
@@ -511,10 +509,20 @@ private:
|
|||||||
bool _IsConst1,
|
bool _IsConst1,
|
||||||
bool _IsConst2,
|
bool _IsConst2,
|
||||||
class _BinaryPredicate,
|
class _BinaryPredicate,
|
||||||
__enable_if_t<__desugars_to_v<__equal_tag, _BinaryPredicate, bool, bool>, int> >
|
class _Proj1,
|
||||||
|
class _Proj2,
|
||||||
|
__enable_if_t<__is_identity<_Proj1>::value && __is_identity<_Proj2>::value &&
|
||||||
|
__desugars_to_v<__equal_tag, _BinaryPredicate, bool, bool>,
|
||||||
|
int> >
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool __equal_iter_impl(
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool __equal_iter_impl(
|
||||||
__bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst2>, _BinaryPredicate);
|
__bit_iterator<_Dp, _IsConst1>,
|
||||||
template <class _Dp,
|
__bit_iterator<_Dp, _IsConst1>,
|
||||||
|
__bit_iterator<_Dp, _IsConst2>,
|
||||||
|
_BinaryPredicate,
|
||||||
|
_Proj1&,
|
||||||
|
_Proj2&);
|
||||||
|
template <bool,
|
||||||
|
class _Dp,
|
||||||
bool _IsConst1,
|
bool _IsConst1,
|
||||||
bool _IsConst2,
|
bool _IsConst2,
|
||||||
class _Pred,
|
class _Pred,
|
||||||
@@ -537,6 +545,187 @@ private:
|
|||||||
template <bool _ToCount, class _Dp, bool _IC>
|
template <bool _ToCount, class _Dp, bool _IC>
|
||||||
friend typename __bit_iterator<_Dp, _IC>::difference_type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
friend typename __bit_iterator<_Dp, _IC>::difference_type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||||
__count_bool(__bit_iterator<_Dp, _IC>, typename __size_difference_type_traits<_Dp>::size_type);
|
__count_bool(__bit_iterator<_Dp, _IC>, typename __size_difference_type_traits<_Dp>::size_type);
|
||||||
|
|
||||||
|
template <class, class...>
|
||||||
|
friend struct __specialized_algorithm;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Cp>
|
||||||
|
struct __specialized_algorithm<_Algorithm::__fill_n, __single_iterator<__bit_iterator<_Cp, false> > > {
|
||||||
|
static const bool __has_algorithm = true;
|
||||||
|
|
||||||
|
template <bool _FillVal>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void
|
||||||
|
__impl(__bit_iterator<_Cp, false> __first, typename __size_difference_type_traits<_Cp>::size_type __n) {
|
||||||
|
using _It = __bit_iterator<_Cp, false>;
|
||||||
|
using __storage_type = typename _It::__storage_type;
|
||||||
|
|
||||||
|
const int __bits_per_word = _It::__bits_per_word;
|
||||||
|
// do first partial word
|
||||||
|
if (__first.__ctz_ != 0) {
|
||||||
|
__storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
|
||||||
|
__storage_type __dn = std::min(__clz_f, __n);
|
||||||
|
std::__fill_masked_range(std::__to_address(__first.__seg_), __clz_f - __dn, __first.__ctz_, _FillVal);
|
||||||
|
__n -= __dn;
|
||||||
|
++__first.__seg_;
|
||||||
|
}
|
||||||
|
// do middle whole words
|
||||||
|
__storage_type __nw = __n / __bits_per_word;
|
||||||
|
std::__fill_n(std::__to_address(__first.__seg_), __nw, _FillVal ? static_cast<__storage_type>(-1) : 0);
|
||||||
|
__n -= __nw * __bits_per_word;
|
||||||
|
// do last partial word
|
||||||
|
if (__n > 0) {
|
||||||
|
__first.__seg_ += __nw;
|
||||||
|
std::__fill_masked_range(std::__to_address(__first.__seg_), __bits_per_word - __n, 0u, _FillVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _Size, class _Tp>
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static __bit_iterator<_Cp, false>
|
||||||
|
operator()(__bit_iterator<_Cp, false> __first, _Size __n, const _Tp& __value) {
|
||||||
|
if (__n > 0) {
|
||||||
|
if (__value)
|
||||||
|
__impl<true>(__first, __n);
|
||||||
|
else
|
||||||
|
__impl<false>(__first, __n);
|
||||||
|
}
|
||||||
|
return __first + __n;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Cp, bool _IsConst>
|
||||||
|
struct __specialized_algorithm<_Algorithm::__copy,
|
||||||
|
__iterator_pair<__bit_iterator<_Cp, _IsConst>, __bit_iterator<_Cp, _IsConst> >,
|
||||||
|
__single_iterator<__bit_iterator<_Cp, false> > > {
|
||||||
|
static const bool __has_algorithm = true;
|
||||||
|
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static __bit_iterator<_Cp, false>
|
||||||
|
__aligned_impl(__bit_iterator<_Cp, _IsConst> __first,
|
||||||
|
__bit_iterator<_Cp, _IsConst> __last,
|
||||||
|
__bit_iterator<_Cp, false> __result) {
|
||||||
|
using _In = __bit_iterator<_Cp, _IsConst>;
|
||||||
|
using difference_type = typename _In::difference_type;
|
||||||
|
using __storage_type = typename _In::__storage_type;
|
||||||
|
|
||||||
|
const int __bits_per_word = _In::__bits_per_word;
|
||||||
|
difference_type __n = __last - __first;
|
||||||
|
if (__n > 0) {
|
||||||
|
// do first word
|
||||||
|
if (__first.__ctz_ != 0) {
|
||||||
|
unsigned __clz = __bits_per_word - __first.__ctz_;
|
||||||
|
difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
|
||||||
|
__n -= __dn;
|
||||||
|
__storage_type __m = std::__middle_mask<__storage_type>(__clz - __dn, __first.__ctz_);
|
||||||
|
__storage_type __b = *__first.__seg_ & __m;
|
||||||
|
*__result.__seg_ &= ~__m;
|
||||||
|
*__result.__seg_ |= __b;
|
||||||
|
__result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
|
||||||
|
__result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
|
||||||
|
++__first.__seg_;
|
||||||
|
// __first.__ctz_ = 0;
|
||||||
|
}
|
||||||
|
// __first.__ctz_ == 0;
|
||||||
|
// do middle words
|
||||||
|
__storage_type __nw = __n / __bits_per_word;
|
||||||
|
std::copy(std::__to_address(__first.__seg_),
|
||||||
|
std::__to_address(__first.__seg_ + __nw),
|
||||||
|
std::__to_address(__result.__seg_));
|
||||||
|
__n -= __nw * __bits_per_word;
|
||||||
|
__result.__seg_ += __nw;
|
||||||
|
// do last word
|
||||||
|
if (__n > 0) {
|
||||||
|
__first.__seg_ += __nw;
|
||||||
|
__storage_type __m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
|
||||||
|
__storage_type __b = *__first.__seg_ & __m;
|
||||||
|
*__result.__seg_ &= ~__m;
|
||||||
|
*__result.__seg_ |= __b;
|
||||||
|
__result.__ctz_ = static_cast<unsigned>(__n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return __result;
|
||||||
|
}
|
||||||
|
|
||||||
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static __bit_iterator<_Cp, false>
|
||||||
|
__unaligned_impl(__bit_iterator<_Cp, _IsConst> __first,
|
||||||
|
__bit_iterator<_Cp, _IsConst> __last,
|
||||||
|
__bit_iterator<_Cp, false> __result) {
|
||||||
|
using _In = __bit_iterator<_Cp, _IsConst>;
|
||||||
|
using difference_type = typename _In::difference_type;
|
||||||
|
using __storage_type = typename _In::__storage_type;
|
||||||
|
|
||||||
|
const int __bits_per_word = _In::__bits_per_word;
|
||||||
|
difference_type __n = __last - __first;
|
||||||
|
if (__n > 0) {
|
||||||
|
// do first word
|
||||||
|
if (__first.__ctz_ != 0) {
|
||||||
|
unsigned __clz_f = __bits_per_word - __first.__ctz_;
|
||||||
|
difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
|
||||||
|
__n -= __dn;
|
||||||
|
__storage_type __m = std::__middle_mask<__storage_type>(__clz_f - __dn, __first.__ctz_);
|
||||||
|
__storage_type __b = *__first.__seg_ & __m;
|
||||||
|
unsigned __clz_r = __bits_per_word - __result.__ctz_;
|
||||||
|
__storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
|
||||||
|
__m = std::__middle_mask<__storage_type>(__clz_r - __ddn, __result.__ctz_);
|
||||||
|
*__result.__seg_ &= ~__m;
|
||||||
|
if (__result.__ctz_ > __first.__ctz_)
|
||||||
|
*__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
|
||||||
|
else
|
||||||
|
*__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
|
||||||
|
__result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
|
||||||
|
__result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
|
||||||
|
__dn -= __ddn;
|
||||||
|
if (__dn > 0) {
|
||||||
|
__m = std::__trailing_mask<__storage_type>(__bits_per_word - __dn);
|
||||||
|
*__result.__seg_ &= ~__m;
|
||||||
|
*__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
|
||||||
|
__result.__ctz_ = static_cast<unsigned>(__dn);
|
||||||
|
}
|
||||||
|
++__first.__seg_;
|
||||||
|
// __first.__ctz_ = 0;
|
||||||
|
}
|
||||||
|
// __first.__ctz_ == 0;
|
||||||
|
// do middle words
|
||||||
|
unsigned __clz_r = __bits_per_word - __result.__ctz_;
|
||||||
|
__storage_type __m = std::__leading_mask<__storage_type>(__result.__ctz_);
|
||||||
|
for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) {
|
||||||
|
__storage_type __b = *__first.__seg_;
|
||||||
|
*__result.__seg_ &= ~__m;
|
||||||
|
*__result.__seg_ |= __b << __result.__ctz_;
|
||||||
|
++__result.__seg_;
|
||||||
|
*__result.__seg_ &= __m;
|
||||||
|
*__result.__seg_ |= __b >> __clz_r;
|
||||||
|
}
|
||||||
|
// do last word
|
||||||
|
if (__n > 0) {
|
||||||
|
__m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
|
||||||
|
__storage_type __b = *__first.__seg_ & __m;
|
||||||
|
__storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r));
|
||||||
|
__m = std::__middle_mask<__storage_type>(__clz_r - __dn, __result.__ctz_);
|
||||||
|
*__result.__seg_ &= ~__m;
|
||||||
|
*__result.__seg_ |= __b << __result.__ctz_;
|
||||||
|
__result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
|
||||||
|
__result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
|
||||||
|
__n -= __dn;
|
||||||
|
if (__n > 0) {
|
||||||
|
__m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
|
||||||
|
*__result.__seg_ &= ~__m;
|
||||||
|
*__result.__seg_ |= __b >> __dn;
|
||||||
|
__result.__ctz_ = static_cast<unsigned>(__n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return __result;
|
||||||
|
}
|
||||||
|
|
||||||
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
|
_LIBCPP_CONSTEXPR_SINCE_CXX20 static pair<__bit_iterator<_Cp, _IsConst>, __bit_iterator<_Cp, false> >
|
||||||
|
operator()(__bit_iterator<_Cp, _IsConst> __first,
|
||||||
|
__bit_iterator<_Cp, _IsConst> __last,
|
||||||
|
__bit_iterator<_Cp, false> __result) {
|
||||||
|
if (__first.__ctz_ == __result.__ctz_)
|
||||||
|
return std::make_pair(__last, __aligned_impl(__first, __last, __result));
|
||||||
|
return std::make_pair(__last, __unaligned_impl(__first, __last, __result));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|||||||
+1
-1
@@ -18,8 +18,8 @@
|
|||||||
#include <__memory/addressof.h>
|
#include <__memory/addressof.h>
|
||||||
#include <__system_error/errc.h>
|
#include <__system_error/errc.h>
|
||||||
#include <__type_traits/enable_if.h>
|
#include <__type_traits/enable_if.h>
|
||||||
#include <__type_traits/integral_constant.h>
|
|
||||||
#include <__type_traits/is_integral.h>
|
#include <__type_traits/is_integral.h>
|
||||||
|
#include <__type_traits/is_signed.h>
|
||||||
#include <__type_traits/is_unsigned.h>
|
#include <__type_traits/is_unsigned.h>
|
||||||
#include <__type_traits/make_unsigned.h>
|
#include <__type_traits/make_unsigned.h>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 17
|
#if _LIBCPP_STD_VER >= 17
|
||||||
|
|
||||||
struct _LIBCPP_EXPORTED_FROM_ABI from_chars_result {
|
struct from_chars_result {
|
||||||
const char* ptr;
|
const char* ptr;
|
||||||
errc ec;
|
errc ec;
|
||||||
# if _LIBCPP_STD_VER >= 20
|
# if _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <__type_traits/integral_constant.h>
|
#include <__type_traits/integral_constant.h>
|
||||||
#include <__type_traits/is_integral.h>
|
#include <__type_traits/is_integral.h>
|
||||||
#include <__type_traits/is_same.h>
|
#include <__type_traits/is_same.h>
|
||||||
|
#include <__type_traits/is_signed.h>
|
||||||
#include <__type_traits/make_32_64_or_128_bit.h>
|
#include <__type_traits/make_32_64_or_128_bit.h>
|
||||||
#include <__type_traits/make_unsigned.h>
|
#include <__type_traits/make_unsigned.h>
|
||||||
#include <__utility/unreachable.h>
|
#include <__utility/unreachable.h>
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 17
|
#if _LIBCPP_STD_VER >= 17
|
||||||
|
|
||||||
struct _LIBCPP_EXPORTED_FROM_ABI to_chars_result {
|
struct to_chars_result {
|
||||||
char* ptr;
|
char* ptr;
|
||||||
errc ec;
|
errc ec;
|
||||||
# if _LIBCPP_STD_VER >= 20
|
# if _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
+3
-24
@@ -113,31 +113,10 @@ struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__u
|
|||||||
};
|
};
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
template <typename _Tp>
|
|
||||||
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
|
|
||||||
__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r) {
|
|
||||||
auto __c = __a * __b;
|
|
||||||
__r = __c;
|
|
||||||
return __c > numeric_limits<unsigned char>::max();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename _Tp>
|
|
||||||
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
|
|
||||||
__mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r) {
|
|
||||||
auto __c = __a * __b;
|
|
||||||
__r = __c;
|
|
||||||
return __c > numeric_limits<unsigned short>::max();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename _Tp>
|
|
||||||
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool __mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) {
|
|
||||||
static_assert(is_unsigned<_Tp>::value, "");
|
|
||||||
return __builtin_mul_overflow(__a, __b, std::addressof(__r));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename _Tp, typename _Up>
|
template <typename _Tp, typename _Up>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI bool _LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r) {
|
_LIBCPP_HIDE_FROM_ABI bool _LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r) {
|
||||||
return __itoa::__mul_overflowed(__a, static_cast<_Tp>(__b), __r);
|
static_assert(is_unsigned<_Tp>::value);
|
||||||
|
return __builtin_mul_overflow(__a, static_cast<_Tp>(__b), std::addressof(__r));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _Tp>
|
template <typename _Tp>
|
||||||
|
|||||||
Vendored
+11
@@ -13,6 +13,8 @@
|
|||||||
#include <__chrono/duration.h>
|
#include <__chrono/duration.h>
|
||||||
#include <__compare/ordering.h>
|
#include <__compare/ordering.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__cstddef/size_t.h>
|
||||||
|
#include <__functional/hash.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
@@ -92,6 +94,15 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator-=(const days& __dd) no
|
|||||||
|
|
||||||
} // namespace chrono
|
} // namespace chrono
|
||||||
|
|
||||||
|
# if _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::day> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::day& __d) noexcept { return static_cast<unsigned>(__d); }
|
||||||
|
};
|
||||||
|
|
||||||
|
# endif // _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
+58
-33
@@ -13,6 +13,8 @@
|
|||||||
#include <__compare/ordering.h>
|
#include <__compare/ordering.h>
|
||||||
#include <__compare/three_way_comparable.h>
|
#include <__compare/three_way_comparable.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__cstddef/size_t.h>
|
||||||
|
#include <__functional/hash.h>
|
||||||
#include <__type_traits/common_type.h>
|
#include <__type_traits/common_type.h>
|
||||||
#include <__type_traits/enable_if.h>
|
#include <__type_traits/enable_if.h>
|
||||||
#include <__type_traits/is_convertible.h>
|
#include <__type_traits/is_convertible.h>
|
||||||
@@ -102,7 +104,8 @@ struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class _ToDuration, class _Rep, class _Period, __enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
template <class _ToDuration, class _Rep, class _Period, __enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration duration_cast(const duration<_Rep, _Period>& __fd) {
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration
|
||||||
|
duration_cast(const duration<_Rep, _Period>& __fd) {
|
||||||
return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd);
|
return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,14 +120,18 @@ inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>:
|
|||||||
template <class _Rep>
|
template <class _Rep>
|
||||||
struct duration_values {
|
struct duration_values {
|
||||||
public:
|
public:
|
||||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT { return _Rep(0); }
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT { return _Rep(0); }
|
||||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT { return numeric_limits<_Rep>::max(); }
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT {
|
||||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT { return numeric_limits<_Rep>::lowest(); }
|
return numeric_limits<_Rep>::max();
|
||||||
|
}
|
||||||
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {
|
||||||
|
return numeric_limits<_Rep>::lowest();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 17
|
#if _LIBCPP_STD_VER >= 17
|
||||||
template <class _ToDuration, class _Rep, class _Period, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
template <class _ToDuration, class _Rep, class _Period, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration floor(const duration<_Rep, _Period>& __d) {
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration floor(const duration<_Rep, _Period>& __d) {
|
||||||
_ToDuration __t = chrono::duration_cast<_ToDuration>(__d);
|
_ToDuration __t = chrono::duration_cast<_ToDuration>(__d);
|
||||||
if (__t > __d)
|
if (__t > __d)
|
||||||
__t = __t - _ToDuration{1};
|
__t = __t - _ToDuration{1};
|
||||||
@@ -132,7 +139,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration floor(const duration<
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class _ToDuration, class _Rep, class _Period, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
template <class _ToDuration, class _Rep, class _Period, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration ceil(const duration<_Rep, _Period>& __d) {
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration ceil(const duration<_Rep, _Period>& __d) {
|
||||||
_ToDuration __t = chrono::duration_cast<_ToDuration>(__d);
|
_ToDuration __t = chrono::duration_cast<_ToDuration>(__d);
|
||||||
if (__t < __d)
|
if (__t < __d)
|
||||||
__t = __t + _ToDuration{1};
|
__t = __t + _ToDuration{1};
|
||||||
@@ -140,7 +147,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration ceil(const duration<_
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class _ToDuration, class _Rep, class _Period, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
template <class _ToDuration, class _Rep, class _Period, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration round(const duration<_Rep, _Period>& __d) {
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration round(const duration<_Rep, _Period>& __d) {
|
||||||
_ToDuration __lower = chrono::floor<_ToDuration>(__d);
|
_ToDuration __lower = chrono::floor<_ToDuration>(__d);
|
||||||
_ToDuration __upper = __lower + _ToDuration{1};
|
_ToDuration __upper = __lower + _ToDuration{1};
|
||||||
auto __lower_diff = __d - __lower;
|
auto __lower_diff = __d - __lower;
|
||||||
@@ -220,14 +227,14 @@ public:
|
|||||||
|
|
||||||
// observer
|
// observer
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR rep count() const { return __rep_; }
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR rep count() const { return __rep_; }
|
||||||
|
|
||||||
// arithmetic
|
// arithmetic
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<duration>::type operator+() const {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<duration>::type operator+() const {
|
||||||
return typename common_type<duration>::type(*this);
|
return typename common_type<duration>::type(*this);
|
||||||
}
|
}
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<duration>::type operator-() const {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<duration>::type operator-() const {
|
||||||
return typename common_type<duration>::type(-__rep_);
|
return typename common_type<duration>::type(-__rep_);
|
||||||
}
|
}
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator++() {
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator++() {
|
||||||
@@ -269,13 +276,13 @@ public:
|
|||||||
|
|
||||||
// special values
|
// special values
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {
|
||||||
return duration(duration_values<rep>::zero());
|
return duration(duration_values<rep>::zero());
|
||||||
}
|
}
|
||||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {
|
||||||
return duration(duration_values<rep>::min());
|
return duration(duration_values<rep>::min());
|
||||||
}
|
}
|
||||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {
|
||||||
return duration(duration_values<rep>::max());
|
return duration(duration_values<rep>::max());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -389,7 +396,7 @@ operator<=>(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Perio
|
|||||||
// Duration +
|
// Duration +
|
||||||
|
|
||||||
template <class _Rep1, class _Period1, class _Rep2, class _Period2>
|
template <class _Rep1, class _Period1, class _Rep2, class _Period2>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
|
||||||
typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
|
typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
|
||||||
operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
|
operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
|
||||||
typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
|
typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
|
||||||
@@ -399,7 +406,7 @@ operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2
|
|||||||
// Duration -
|
// Duration -
|
||||||
|
|
||||||
template <class _Rep1, class _Period1, class _Rep2, class _Period2>
|
template <class _Rep1, class _Period1, class _Rep2, class _Period2>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
|
||||||
typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
|
typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
|
||||||
operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
|
operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
|
||||||
typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
|
typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
|
||||||
@@ -412,7 +419,8 @@ template <class _Rep1,
|
|||||||
class _Period,
|
class _Period,
|
||||||
class _Rep2,
|
class _Rep2,
|
||||||
__enable_if_t<is_convertible<const _Rep2&, typename common_type<_Rep1, _Rep2>::type>::value, int> = 0>
|
__enable_if_t<is_convertible<const _Rep2&, typename common_type<_Rep1, _Rep2>::type>::value, int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
|
||||||
|
_LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
|
||||||
operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) {
|
operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) {
|
||||||
typedef typename common_type<_Rep1, _Rep2>::type _Cr;
|
typedef typename common_type<_Rep1, _Rep2>::type _Cr;
|
||||||
typedef duration<_Cr, _Period> _Cd;
|
typedef duration<_Cr, _Period> _Cd;
|
||||||
@@ -423,7 +431,8 @@ template <class _Rep1,
|
|||||||
class _Period,
|
class _Period,
|
||||||
class _Rep2,
|
class _Rep2,
|
||||||
__enable_if_t<is_convertible<const _Rep1&, typename common_type<_Rep1, _Rep2>::type>::value, int> = 0>
|
__enable_if_t<is_convertible<const _Rep1&, typename common_type<_Rep1, _Rep2>::type>::value, int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
|
||||||
|
_LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
|
||||||
operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) {
|
operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) {
|
||||||
return __d * __s;
|
return __d * __s;
|
||||||
}
|
}
|
||||||
@@ -436,7 +445,8 @@ template <class _Rep1,
|
|||||||
__enable_if_t<!__is_duration_v<_Rep2> &&
|
__enable_if_t<!__is_duration_v<_Rep2> &&
|
||||||
is_convertible<const _Rep2&, typename common_type<_Rep1, _Rep2>::type>::value,
|
is_convertible<const _Rep2&, typename common_type<_Rep1, _Rep2>::type>::value,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
|
||||||
|
_LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
|
||||||
operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) {
|
operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) {
|
||||||
typedef typename common_type<_Rep1, _Rep2>::type _Cr;
|
typedef typename common_type<_Rep1, _Rep2>::type _Cr;
|
||||||
typedef duration<_Cr, _Period> _Cd;
|
typedef duration<_Cr, _Period> _Cd;
|
||||||
@@ -444,7 +454,7 @@ operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class _Rep1, class _Period1, class _Rep2, class _Period2>
|
template <class _Rep1, class _Period1, class _Rep2, class _Period2>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<_Rep1, _Rep2>::type
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<_Rep1, _Rep2>::type
|
||||||
operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
|
operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
|
||||||
typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct;
|
typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct;
|
||||||
return _Ct(__lhs).count() / _Ct(__rhs).count();
|
return _Ct(__lhs).count() / _Ct(__rhs).count();
|
||||||
@@ -458,7 +468,8 @@ template <class _Rep1,
|
|||||||
__enable_if_t<!__is_duration_v<_Rep2> &&
|
__enable_if_t<!__is_duration_v<_Rep2> &&
|
||||||
is_convertible<const _Rep2&, typename common_type<_Rep1, _Rep2>::type>::value,
|
is_convertible<const _Rep2&, typename common_type<_Rep1, _Rep2>::type>::value,
|
||||||
int> = 0>
|
int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
|
||||||
|
_LIBCPP_CONSTEXPR duration<typename common_type<_Rep1, _Rep2>::type, _Period>
|
||||||
operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) {
|
operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) {
|
||||||
typedef typename common_type<_Rep1, _Rep2>::type _Cr;
|
typedef typename common_type<_Rep1, _Rep2>::type _Cr;
|
||||||
typedef duration<_Cr, _Period> _Cd;
|
typedef duration<_Cr, _Period> _Cd;
|
||||||
@@ -466,7 +477,7 @@ operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class _Rep1, class _Period1, class _Rep2, class _Period2>
|
template <class _Rep1, class _Period1, class _Rep2, class _Period2>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
|
||||||
typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
|
typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
|
||||||
operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
|
operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
|
||||||
typedef typename common_type<_Rep1, _Rep2>::type _Cr;
|
typedef typename common_type<_Rep1, _Rep2>::type _Cr;
|
||||||
@@ -481,51 +492,53 @@ operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2
|
|||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
inline namespace chrono_literals {
|
inline namespace chrono_literals {
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr chrono::hours operator""h(unsigned long long __h) {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours operator""h(unsigned long long __h) {
|
||||||
return chrono::hours(static_cast<chrono::hours::rep>(__h));
|
return chrono::hours(static_cast<chrono::hours::rep>(__h));
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, ratio<3600, 1>> operator""h(long double __h) {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, ratio<3600, 1>>
|
||||||
|
operator""h(long double __h) {
|
||||||
return chrono::duration<long double, ratio<3600, 1>>(__h);
|
return chrono::duration<long double, ratio<3600, 1>>(__h);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes operator""min(unsigned long long __m) {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes operator""min(unsigned long long __m) {
|
||||||
return chrono::minutes(static_cast<chrono::minutes::rep>(__m));
|
return chrono::minutes(static_cast<chrono::minutes::rep>(__m));
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, ratio<60, 1>> operator""min(long double __m) {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, ratio<60, 1>>
|
||||||
|
operator""min(long double __m) {
|
||||||
return chrono::duration<long double, ratio<60, 1>>(__m);
|
return chrono::duration<long double, ratio<60, 1>>(__m);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds operator""s(unsigned long long __s) {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds operator""s(unsigned long long __s) {
|
||||||
return chrono::seconds(static_cast<chrono::seconds::rep>(__s));
|
return chrono::seconds(static_cast<chrono::seconds::rep>(__s));
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double> operator""s(long double __s) {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double> operator""s(long double __s) {
|
||||||
return chrono::duration<long double>(__s);
|
return chrono::duration<long double>(__s);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr chrono::milliseconds operator""ms(unsigned long long __ms) {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::milliseconds operator""ms(unsigned long long __ms) {
|
||||||
return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(__ms));
|
return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(__ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, milli> operator""ms(long double __ms) {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, milli> operator""ms(long double __ms) {
|
||||||
return chrono::duration<long double, milli>(__ms);
|
return chrono::duration<long double, milli>(__ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr chrono::microseconds operator""us(unsigned long long __us) {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::microseconds operator""us(unsigned long long __us) {
|
||||||
return chrono::microseconds(static_cast<chrono::microseconds::rep>(__us));
|
return chrono::microseconds(static_cast<chrono::microseconds::rep>(__us));
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, micro> operator""us(long double __us) {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, micro> operator""us(long double __us) {
|
||||||
return chrono::duration<long double, micro>(__us);
|
return chrono::duration<long double, micro>(__us);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) {
|
||||||
return chrono::nanoseconds(static_cast<chrono::nanoseconds::rep>(__ns));
|
return chrono::nanoseconds(static_cast<chrono::nanoseconds::rep>(__ns));
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, nano> operator""ns(long double __ns) {
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, nano> operator""ns(long double __ns) {
|
||||||
return chrono::duration<long double, nano>(__ns);
|
return chrono::duration<long double, nano>(__ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,6 +551,18 @@ using namespace literals::chrono_literals;
|
|||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 14
|
#endif // _LIBCPP_STD_VER >= 14
|
||||||
|
|
||||||
|
#if _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
|
template <class _Rep, class _Period>
|
||||||
|
requires __has_enabled_hash<_Rep>::value
|
||||||
|
struct hash<chrono::duration<_Rep, _Period>> {
|
||||||
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::duration<_Rep, _Period>& __d) {
|
||||||
|
return hash<_Rep>{}(__d.count());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
_LIBCPP_POP_MACROS
|
_LIBCPP_POP_MACROS
|
||||||
|
|||||||
+4
-2
@@ -60,16 +60,18 @@ struct _FilesystemClock {
|
|||||||
|
|
||||||
_LIBCPP_EXPORTED_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false;
|
_LIBCPP_EXPORTED_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false;
|
||||||
|
|
||||||
_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_EXPORTED_FROM_ABI static time_point now() noexcept;
|
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI static time_point now() noexcept;
|
||||||
|
|
||||||
# if _LIBCPP_STD_VER >= 20
|
# if _LIBCPP_STD_VER >= 20
|
||||||
template <class _Duration>
|
template <class _Duration>
|
||||||
|
[[nodiscard]]
|
||||||
_LIBCPP_HIDE_FROM_ABI static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) {
|
_LIBCPP_HIDE_FROM_ABI static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) {
|
||||||
return chrono::sys_time<_Duration>(__t.time_since_epoch());
|
return chrono::sys_time<_Duration>(__t.time_since_epoch());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Duration>
|
template <class _Duration>
|
||||||
_LIBCPP_HIDE_FROM_ABI static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static chrono::file_time<_Duration>
|
||||||
|
from_sys(const chrono::sys_time<_Duration>& __t) {
|
||||||
return chrono::file_time<_Duration>(__t.time_since_epoch());
|
return chrono::file_time<_Duration>(__t.time_since_epoch());
|
||||||
}
|
}
|
||||||
# endif // _LIBCPP_STD_VER >= 20
|
# endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef _LIBCPP___CHRONO_IS_CLOCK_H
|
||||||
|
#define _LIBCPP___CHRONO_IS_CLOCK_H
|
||||||
|
|
||||||
|
#include <__config>
|
||||||
|
|
||||||
|
#include <__chrono/duration.h>
|
||||||
|
#include <__chrono/time_point.h>
|
||||||
|
#include <__concepts/same_as.h>
|
||||||
|
#include <__type_traits/integral_constant.h>
|
||||||
|
#include <__type_traits/is_arithmetic.h>
|
||||||
|
#include <__type_traits/is_class.h>
|
||||||
|
#include <__type_traits/is_union.h>
|
||||||
|
#include <ratio>
|
||||||
|
|
||||||
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
|
# pragma GCC system_header
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
|
namespace chrono {
|
||||||
|
|
||||||
|
// Helper to check that _Tp::time_point has the form time_point<_, typename _Tp::duration>.
|
||||||
|
template <class _TimePoint, class _ClockType>
|
||||||
|
inline constexpr bool __is_valid_clock_time_point_v = false;
|
||||||
|
|
||||||
|
template <class _TimePointClock, class _ClockType>
|
||||||
|
inline constexpr bool
|
||||||
|
__is_valid_clock_time_point_v<time_point<_TimePointClock, typename _ClockType::duration>, _ClockType> = true;
|
||||||
|
|
||||||
|
// Check if a clock satisfies the Cpp17Clock requirements as defined in [time.clock.req]
|
||||||
|
template <class _Tp>
|
||||||
|
_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_clock_v = requires {
|
||||||
|
typename _Tp::rep;
|
||||||
|
requires is_arithmetic_v<typename _Tp::rep> || is_class_v<typename _Tp::rep> || is_union_v<typename _Tp::rep>;
|
||||||
|
|
||||||
|
typename _Tp::period;
|
||||||
|
requires __is_ratio_v<typename _Tp::period>;
|
||||||
|
|
||||||
|
typename _Tp::duration;
|
||||||
|
requires same_as<typename _Tp::duration, duration<typename _Tp::rep, typename _Tp::period>>;
|
||||||
|
|
||||||
|
typename _Tp::time_point;
|
||||||
|
requires __is_valid_clock_time_point_v<typename _Tp::time_point, _Tp>;
|
||||||
|
|
||||||
|
_Tp::is_steady;
|
||||||
|
requires same_as<decltype((_Tp::is_steady)), const bool&>;
|
||||||
|
|
||||||
|
_Tp::now();
|
||||||
|
requires same_as<decltype(_Tp::now()), typename _Tp::time_point>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Tp>
|
||||||
|
struct _LIBCPP_NO_SPECIALIZATIONS is_clock : bool_constant<is_clock_v<_Tp>> {};
|
||||||
|
|
||||||
|
} // namespace chrono
|
||||||
|
|
||||||
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
|
#endif // _LIBCPP_STD_VER
|
||||||
|
#endif // _LIBCPP___CHRONO_IS_CLOCK_H
|
||||||
+13
@@ -22,6 +22,8 @@
|
|||||||
# include <__compare/ordering.h>
|
# include <__compare/ordering.h>
|
||||||
# include <__compare/three_way_comparable.h>
|
# include <__compare/three_way_comparable.h>
|
||||||
# include <__config>
|
# include <__config>
|
||||||
|
# include <__cstddef/size_t.h>
|
||||||
|
# include <__functional/hash.h>
|
||||||
# include <__utility/private_constructor_tag.h>
|
# include <__utility/private_constructor_tag.h>
|
||||||
|
|
||||||
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
@@ -122,6 +124,17 @@ private:
|
|||||||
|
|
||||||
} // namespace chrono
|
} // namespace chrono
|
||||||
|
|
||||||
|
# if _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::leap_second> {
|
||||||
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::leap_second& __lp) noexcept {
|
||||||
|
return std::__hash_combine(hash<chrono::sys_seconds>{}(__lp.date()), hash<chrono::seconds>{}(__lp.value()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
# endif // _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
# endif // _LIBCPP_STD_VER >= 20
|
# endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|||||||
Vendored
+13
@@ -13,6 +13,8 @@
|
|||||||
#include <__chrono/duration.h>
|
#include <__chrono/duration.h>
|
||||||
#include <__compare/ordering.h>
|
#include <__compare/ordering.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__cstddef/size_t.h>
|
||||||
|
#include <__functional/hash.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
@@ -108,6 +110,17 @@ inline constexpr month December{12};
|
|||||||
|
|
||||||
} // namespace chrono
|
} // namespace chrono
|
||||||
|
|
||||||
|
# if _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::month> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month& __m) noexcept {
|
||||||
|
return static_cast<unsigned>(__m);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
# endif // _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
+22
@@ -13,6 +13,8 @@
|
|||||||
#include <__chrono/month.h>
|
#include <__chrono/month.h>
|
||||||
#include <__chrono/weekday.h>
|
#include <__chrono/weekday.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__cstddef/size_t.h>
|
||||||
|
#include <__functional/hash.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
@@ -98,6 +100,26 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last operator/(const weekda
|
|||||||
}
|
}
|
||||||
} // namespace chrono
|
} // namespace chrono
|
||||||
|
|
||||||
|
# if _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::month_weekday> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_weekday& __mw) noexcept {
|
||||||
|
return std::__hash_combine(
|
||||||
|
hash<chrono::month>{}(__mw.month()), hash<chrono::weekday_indexed>{}(__mw.weekday_indexed()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::month_weekday_last> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_weekday_last& __mwl) noexcept {
|
||||||
|
return std::__hash_combine(
|
||||||
|
hash<chrono::month>{}(__mwl.month()), hash<chrono::weekday_last>{}(__mwl.weekday_last()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
# endif // _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
+20
@@ -15,6 +15,8 @@
|
|||||||
#include <__chrono/month.h>
|
#include <__chrono/month.h>
|
||||||
#include <__compare/ordering.h>
|
#include <__compare/ordering.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__cstddef/size_t.h>
|
||||||
|
#include <__functional/hash.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
@@ -126,6 +128,24 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(last_spec, int _
|
|||||||
|
|
||||||
} // namespace chrono
|
} // namespace chrono
|
||||||
|
|
||||||
|
# if _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::month_day> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_day& __md) noexcept {
|
||||||
|
return std::__hash_combine(hash<chrono::month>{}(__md.month()), hash<chrono::day>{}(__md.day()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::month_day_last> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_day_last& __mdl) noexcept {
|
||||||
|
return hash<chrono::month>{}(__mdl.month());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
# endif // _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ public:
|
|||||||
typedef chrono::time_point<steady_clock, duration> time_point;
|
typedef chrono::time_point<steady_clock, duration> time_point;
|
||||||
static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = true;
|
static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = true;
|
||||||
|
|
||||||
static time_point now() _NOEXCEPT;
|
[[__nodiscard__]] static time_point now() _NOEXCEPT;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -31,9 +31,9 @@ public:
|
|||||||
typedef chrono::time_point<system_clock> time_point;
|
typedef chrono::time_point<system_clock> time_point;
|
||||||
static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false;
|
static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false;
|
||||||
|
|
||||||
static time_point now() _NOEXCEPT;
|
[[__nodiscard__]] static time_point now() _NOEXCEPT;
|
||||||
static time_t to_time_t(const time_point& __t) _NOEXCEPT;
|
[[__nodiscard__]] static time_t to_time_t(const time_point& __t) _NOEXCEPT;
|
||||||
static time_point from_time_t(time_t __t) _NOEXCEPT;
|
[[__nodiscard__]] static time_point from_time_t(time_t __t) _NOEXCEPT;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 20
|
#if _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
+37
-13
@@ -14,6 +14,8 @@
|
|||||||
#include <__compare/ordering.h>
|
#include <__compare/ordering.h>
|
||||||
#include <__compare/three_way_comparable.h>
|
#include <__compare/three_way_comparable.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__cstddef/size_t.h>
|
||||||
|
#include <__functional/hash.h>
|
||||||
#include <__type_traits/common_type.h>
|
#include <__type_traits/common_type.h>
|
||||||
#include <__type_traits/enable_if.h>
|
#include <__type_traits/enable_if.h>
|
||||||
#include <__type_traits/is_convertible.h>
|
#include <__type_traits/is_convertible.h>
|
||||||
@@ -54,7 +56,9 @@ public:
|
|||||||
|
|
||||||
// observer
|
// observer
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const { return __d_; }
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const {
|
||||||
|
return __d_;
|
||||||
|
}
|
||||||
|
|
||||||
// arithmetic
|
// arithmetic
|
||||||
|
|
||||||
@@ -82,8 +86,12 @@ public:
|
|||||||
|
|
||||||
// special values
|
// special values
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT { return time_point(duration::min()); }
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {
|
||||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT { return time_point(duration::max()); }
|
return time_point(duration::min());
|
||||||
|
}
|
||||||
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {
|
||||||
|
return time_point(duration::max());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace chrono
|
} // namespace chrono
|
||||||
@@ -95,30 +103,33 @@ struct common_type<chrono::time_point<_Clock, _Duration1>, chrono::time_point<_C
|
|||||||
|
|
||||||
namespace chrono {
|
namespace chrono {
|
||||||
|
|
||||||
template <class _ToDuration, class _Clock, class _Duration>
|
template <class _ToDuration, class _Clock, class _Duration, __enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, _ToDuration>
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, _ToDuration>
|
||||||
time_point_cast(const time_point<_Clock, _Duration>& __t) {
|
time_point_cast(const time_point<_Clock, _Duration>& __t) {
|
||||||
return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
|
return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 17
|
#if _LIBCPP_STD_VER >= 17
|
||||||
template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> floor(const time_point<_Clock, _Duration>& __t) {
|
[[nodiscard]] inline
|
||||||
|
_LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> floor(const time_point<_Clock, _Duration>& __t) {
|
||||||
return time_point<_Clock, _ToDuration>{chrono::floor<_ToDuration>(__t.time_since_epoch())};
|
return time_point<_Clock, _ToDuration>{chrono::floor<_ToDuration>(__t.time_since_epoch())};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> ceil(const time_point<_Clock, _Duration>& __t) {
|
[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration>
|
||||||
|
ceil(const time_point<_Clock, _Duration>& __t) {
|
||||||
return time_point<_Clock, _ToDuration>{chrono::ceil<_ToDuration>(__t.time_since_epoch())};
|
return time_point<_Clock, _ToDuration>{chrono::ceil<_ToDuration>(__t.time_since_epoch())};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> round(const time_point<_Clock, _Duration>& __t) {
|
[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration>
|
||||||
|
round(const time_point<_Clock, _Duration>& __t) {
|
||||||
return time_point<_Clock, _ToDuration>{chrono::round<_ToDuration>(__t.time_since_epoch())};
|
return time_point<_Clock, _ToDuration>{chrono::round<_ToDuration>(__t.time_since_epoch())};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Rep, class _Period, enable_if_t<numeric_limits<_Rep>::is_signed, int> = 0>
|
template <class _Rep, class _Period, enable_if_t<numeric_limits<_Rep>::is_signed, int> = 0>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI constexpr duration<_Rep, _Period> abs(duration<_Rep, _Period> __d) {
|
[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr duration<_Rep, _Period> abs(duration<_Rep, _Period> __d) {
|
||||||
return __d >= __d.zero() ? +__d : -__d;
|
return __d >= __d.zero() ? +__d : -__d;
|
||||||
}
|
}
|
||||||
#endif // _LIBCPP_STD_VER >= 17
|
#endif // _LIBCPP_STD_VER >= 17
|
||||||
@@ -188,7 +199,7 @@ operator<=>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock
|
|||||||
// time_point operator+(time_point x, duration y);
|
// time_point operator+(time_point x, duration y);
|
||||||
|
|
||||||
template <class _Clock, class _Duration1, class _Rep2, class _Period2>
|
template <class _Clock, class _Duration1, class _Rep2, class _Period2>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
|
||||||
operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
|
operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
|
||||||
typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr;
|
typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr;
|
||||||
@@ -198,7 +209,7 @@ operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Pe
|
|||||||
// time_point operator+(duration x, time_point y);
|
// time_point operator+(duration x, time_point y);
|
||||||
|
|
||||||
template <class _Rep1, class _Period1, class _Clock, class _Duration2>
|
template <class _Rep1, class _Period1, class _Clock, class _Duration2>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
|
||||||
operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
|
operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
|
||||||
return __rhs + __lhs;
|
return __rhs + __lhs;
|
||||||
@@ -207,7 +218,7 @@ operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Dura
|
|||||||
// time_point operator-(time_point x, duration y);
|
// time_point operator-(time_point x, duration y);
|
||||||
|
|
||||||
template <class _Clock, class _Duration1, class _Rep2, class _Period2>
|
template <class _Clock, class _Duration1, class _Rep2, class _Period2>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
|
||||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
|
_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
|
||||||
operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
|
operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
|
||||||
typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret;
|
typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret;
|
||||||
@@ -217,13 +228,26 @@ operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Pe
|
|||||||
// duration operator-(time_point x, time_point y);
|
// duration operator-(time_point x, time_point y);
|
||||||
|
|
||||||
template <class _Clock, class _Duration1, class _Duration2>
|
template <class _Clock, class _Duration1, class _Duration2>
|
||||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename common_type<_Duration1, _Duration2>::type
|
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||||
|
typename common_type<_Duration1, _Duration2>::type
|
||||||
operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
|
operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
|
||||||
return __lhs.time_since_epoch() - __rhs.time_since_epoch();
|
return __lhs.time_since_epoch() - __rhs.time_since_epoch();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace chrono
|
} // namespace chrono
|
||||||
|
|
||||||
|
#if _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
|
template <class _Clock, class _Duration>
|
||||||
|
requires __has_enabled_hash<_Duration>::value
|
||||||
|
struct hash<chrono::time_point<_Clock, _Duration>> {
|
||||||
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::time_point<_Clock, _Duration>& __tp) {
|
||||||
|
return hash<_Duration>{}(__tp.time_since_epoch());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
_LIBCPP_POP_MACROS
|
_LIBCPP_POP_MACROS
|
||||||
|
|||||||
+25
@@ -15,6 +15,8 @@
|
|||||||
#include <__chrono/system_clock.h>
|
#include <__chrono/system_clock.h>
|
||||||
#include <__chrono/time_point.h>
|
#include <__chrono/time_point.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__cstddef/size_t.h>
|
||||||
|
#include <__functional/hash.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
@@ -160,6 +162,29 @@ inline constexpr weekday Saturday{6};
|
|||||||
|
|
||||||
} // namespace chrono
|
} // namespace chrono
|
||||||
|
|
||||||
|
# if _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::weekday> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday& __w) noexcept { return __w.c_encoding(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::weekday_indexed> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday_indexed& __wi) noexcept {
|
||||||
|
return std::__hash_combine(hash<chrono::weekday>{}(__wi.weekday()), __wi.index());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::weekday_last> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday_last& __wl) noexcept {
|
||||||
|
return hash<chrono::weekday>{}(__wl.weekday());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
# endif // _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
Vendored
+11
@@ -13,6 +13,8 @@
|
|||||||
#include <__chrono/duration.h>
|
#include <__chrono/duration.h>
|
||||||
#include <__compare/ordering.h>
|
#include <__compare/ordering.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__cstddef/size_t.h>
|
||||||
|
#include <__functional/hash.h>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
@@ -109,6 +111,15 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept {
|
|||||||
|
|
||||||
} // namespace chrono
|
} // namespace chrono
|
||||||
|
|
||||||
|
# if _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::year> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year& __y) noexcept { return static_cast<int>(__y); }
|
||||||
|
};
|
||||||
|
|
||||||
|
# endif // _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
+13
@@ -15,6 +15,8 @@
|
|||||||
#include <__chrono/year.h>
|
#include <__chrono/year.h>
|
||||||
#include <__compare/ordering.h>
|
#include <__compare/ordering.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__cstddef/size_t.h>
|
||||||
|
#include <__functional/hash.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
@@ -116,6 +118,17 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator-=(const
|
|||||||
|
|
||||||
} // namespace chrono
|
} // namespace chrono
|
||||||
|
|
||||||
|
# if _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::year_month> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month& __ym) noexcept {
|
||||||
|
return std::__hash_combine(hash<chrono::year>{}(__ym.year()), hash<chrono::month>{}(__ym.month()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
# endif // _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
+23
@@ -21,6 +21,8 @@
|
|||||||
#include <__chrono/year_month.h>
|
#include <__chrono/year_month.h>
|
||||||
#include <__compare/ordering.h>
|
#include <__compare/ordering.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__cstddef/size_t.h>
|
||||||
|
#include <__functional/hash.h>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
@@ -330,6 +332,27 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr bool year_month_day::ok() const noexcept
|
|||||||
|
|
||||||
} // namespace chrono
|
} // namespace chrono
|
||||||
|
|
||||||
|
# if _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::year_month_day> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_day& __ymd) noexcept {
|
||||||
|
return std::__hash_combine(
|
||||||
|
hash<chrono::year>{}(__ymd.year()),
|
||||||
|
std::__hash_combine(hash<chrono::month>{}(__ymd.month()), hash<chrono::day>{}(__ymd.day())));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::year_month_day_last> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_day_last& __ymdl) noexcept {
|
||||||
|
return std::__hash_combine(
|
||||||
|
hash<chrono::year>{}(__ymdl.year()), hash<chrono::month_day_last>{}(__ymdl.month_day_last()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
# endif // _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
#include <__chrono/year_month.h>
|
#include <__chrono/year_month.h>
|
||||||
#include <__chrono/year_month_day.h>
|
#include <__chrono/year_month_day.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <__cstddef/size_t.h>
|
||||||
|
#include <__functional/hash.h>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
@@ -280,6 +282,30 @@ year_month_weekday_last::operator-=(const years& __dy) noexcept {
|
|||||||
|
|
||||||
} // namespace chrono
|
} // namespace chrono
|
||||||
|
|
||||||
|
# if _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::year_month_weekday> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_weekday& __ymw) noexcept {
|
||||||
|
return std::__hash_combine(
|
||||||
|
hash<chrono::year>{}(__ymw.year()),
|
||||||
|
std::__hash_combine(
|
||||||
|
hash<chrono::month>{}(__ymw.month()), hash<chrono::weekday_indexed>{}(__ymw.weekday_indexed())));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<chrono::year_month_weekday_last> {
|
||||||
|
_LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_weekday_last& __ymwl) noexcept {
|
||||||
|
return std::__hash_combine(
|
||||||
|
hash<chrono::year>{}(__ymwl.year()),
|
||||||
|
std::__hash_combine(
|
||||||
|
hash<chrono::month>{}(__ymwl.month()), hash<chrono::weekday_last>{}(__ymwl.weekday_last())));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
# endif // _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|||||||
+16
@@ -24,6 +24,8 @@
|
|||||||
# include <__chrono/tzdb_list.h>
|
# include <__chrono/tzdb_list.h>
|
||||||
# include <__concepts/constructible.h>
|
# include <__concepts/constructible.h>
|
||||||
# include <__config>
|
# include <__config>
|
||||||
|
# include <__cstddef/size_t.h>
|
||||||
|
# include <__functional/hash.h>
|
||||||
# include <__type_traits/common_type.h>
|
# include <__type_traits/common_type.h>
|
||||||
# include <__type_traits/conditional.h>
|
# include <__type_traits/conditional.h>
|
||||||
# include <__type_traits/remove_cvref.h>
|
# include <__type_traits/remove_cvref.h>
|
||||||
@@ -216,6 +218,20 @@ operator==(const zoned_time<_Duration1, _TimeZonePtr>& __lhs, const zoned_time<_
|
|||||||
|
|
||||||
} // namespace chrono
|
} // namespace chrono
|
||||||
|
|
||||||
|
# if _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
|
template <class _Duration, class _TimeZonePtr>
|
||||||
|
requires __has_enabled_hash<_Duration>::value && __has_enabled_hash<_TimeZonePtr>::value
|
||||||
|
struct hash<chrono::zoned_time<_Duration, _TimeZonePtr>> {
|
||||||
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static size_t
|
||||||
|
operator()(const chrono::zoned_time<_Duration, _TimeZonePtr>& __zt) {
|
||||||
|
return std::__hash_combine(
|
||||||
|
hash<chrono::sys_time<_Duration>>{}(__zt.get_sys_time()), hash<_TimeZonePtr>{}(__zt.get_time_zone()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
# endif // _LIBCPP_STD_VER >= 26
|
||||||
|
|
||||||
# endif // _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM &&
|
# endif // _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM &&
|
||||||
// _LIBCPP_HAS_LOCALIZATION
|
// _LIBCPP_HAS_LOCALIZATION
|
||||||
|
|
||||||
|
|||||||
Vendored
+6
-6
@@ -20,12 +20,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||||||
|
|
||||||
#if _LIBCPP_STD_VER >= 20
|
#if _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; }
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; }
|
||||||
_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; }
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; }
|
||||||
_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; }
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; }
|
||||||
_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; }
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; }
|
||||||
_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; }
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; }
|
||||||
_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; }
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; }
|
||||||
|
|
||||||
#endif // _LIBCPP_STD_VER >= 20
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
|
|||||||
+12
-30
@@ -13,7 +13,6 @@
|
|||||||
#include <__compare/compare_three_way.h>
|
#include <__compare/compare_three_way.h>
|
||||||
#include <__compare/ordering.h>
|
#include <__compare/ordering.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__math/exponential_functions.h>
|
|
||||||
#include <__math/traits.h>
|
#include <__math/traits.h>
|
||||||
#include <__type_traits/conditional.h>
|
#include <__type_traits/conditional.h>
|
||||||
#include <__type_traits/decay.h>
|
#include <__type_traits/decay.h>
|
||||||
@@ -53,38 +52,21 @@ struct __fn {
|
|||||||
template <class _Tp, class _Up, class _Dp = decay_t<_Tp>>
|
template <class _Tp, class _Up, class _Dp = decay_t<_Tp>>
|
||||||
requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp>
|
requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp>
|
||||||
_LIBCPP_HIDE_FROM_ABI static constexpr strong_ordering __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept {
|
_LIBCPP_HIDE_FROM_ABI static constexpr strong_ordering __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept {
|
||||||
if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int32_t)) {
|
if constexpr (numeric_limits<_Dp>::is_iec559 &&
|
||||||
int32_t __rx = std::bit_cast<int32_t>(__t);
|
(sizeof(_Dp) == sizeof(int32_t) || sizeof(_Dp) == sizeof(int64_t))) {
|
||||||
int32_t __ry = std::bit_cast<int32_t>(__u);
|
using _IntT = conditional_t<sizeof(_Dp) == sizeof(int32_t), int32_t, int64_t>;
|
||||||
__rx = (__rx < 0) ? (numeric_limits<int32_t>::min() - __rx - 1) : __rx;
|
_IntT __rx = std::bit_cast<_IntT>(__t);
|
||||||
__ry = (__ry < 0) ? (numeric_limits<int32_t>::min() - __ry - 1) : __ry;
|
_IntT __ry = std::bit_cast<_IntT>(__u);
|
||||||
return (__rx <=> __ry);
|
__rx = (__rx < 0) ? (numeric_limits<_IntT>::min() - __rx - 1) : __rx;
|
||||||
} else if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int64_t)) {
|
__ry = (__ry < 0) ? (numeric_limits<_IntT>::min() - __ry - 1) : __ry;
|
||||||
int64_t __rx = std::bit_cast<int64_t>(__t);
|
|
||||||
int64_t __ry = std::bit_cast<int64_t>(__u);
|
|
||||||
__rx = (__rx < 0) ? (numeric_limits<int64_t>::min() - __rx - 1) : __rx;
|
|
||||||
__ry = (__ry < 0) ? (numeric_limits<int64_t>::min() - __ry - 1) : __ry;
|
|
||||||
return (__rx <=> __ry);
|
return (__rx <=> __ry);
|
||||||
} else if (__t < __u) {
|
} else if (__t < __u) {
|
||||||
return strong_ordering::less;
|
return strong_ordering::less;
|
||||||
} else if (__t > __u) {
|
} else if (__t > __u) {
|
||||||
return strong_ordering::greater;
|
return strong_ordering::greater;
|
||||||
} else if (__t == __u) {
|
} else if (__t == __u) {
|
||||||
if constexpr (numeric_limits<_Dp>::radix == 2) {
|
static_assert(numeric_limits<_Dp>::radix == 2, "floating point type with a radix other than 2?");
|
||||||
return __math::signbit(__u) <=> __math::signbit(__t);
|
return __math::signbit(__u) <=> __math::signbit(__t);
|
||||||
} else {
|
|
||||||
// This is bullet 3 of the IEEE754 algorithm, relevant
|
|
||||||
// only for decimal floating-point;
|
|
||||||
// see https://stackoverflow.com/questions/69068075/
|
|
||||||
if (__t == 0 || __math::isinf(__t)) {
|
|
||||||
return __math::signbit(__u) <=> __math::signbit(__t);
|
|
||||||
} else {
|
|
||||||
int __texp, __uexp;
|
|
||||||
(void)__math::frexp(__t, &__texp);
|
|
||||||
(void)__math::frexp(__u, &__uexp);
|
|
||||||
return (__t < 0) ? (__texp <=> __uexp) : (__uexp <=> __texp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// They're unordered, so one of them must be a NAN.
|
// They're unordered, so one of them must be a NAN.
|
||||||
// The order is -QNAN, -SNAN, numbers, +SNAN, +QNAN.
|
// The order is -QNAN, -SNAN, numbers, +SNAN, +QNAN.
|
||||||
@@ -93,9 +75,9 @@ struct __fn {
|
|||||||
bool __t_is_negative = __math::signbit(__t);
|
bool __t_is_negative = __math::signbit(__t);
|
||||||
bool __u_is_negative = __math::signbit(__u);
|
bool __u_is_negative = __math::signbit(__u);
|
||||||
using _IntType =
|
using _IntType =
|
||||||
conditional_t< sizeof(__t) == sizeof(int32_t),
|
conditional_t<sizeof(__t) == sizeof(int32_t),
|
||||||
int32_t,
|
int32_t,
|
||||||
conditional_t< sizeof(__t) == sizeof(int64_t), int64_t, void> >;
|
conditional_t<sizeof(__t) == sizeof(int64_t), int64_t, void>>;
|
||||||
if constexpr (is_same_v<_IntType, void>) {
|
if constexpr (is_same_v<_IntType, void>) {
|
||||||
static_assert(sizeof(_Dp) == 0, "std::strong_order is unimplemented for this floating-point type");
|
static_assert(sizeof(_Dp) == 0, "std::strong_order is unimplemented for this floating-point type");
|
||||||
} else if (__t_is_nan && __u_is_nan) {
|
} else if (__t_is_nan && __u_is_nan) {
|
||||||
|
|||||||
+2
-2
@@ -12,6 +12,7 @@
|
|||||||
#include <__compare/common_comparison_category.h>
|
#include <__compare/common_comparison_category.h>
|
||||||
#include <__compare/ordering.h>
|
#include <__compare/ordering.h>
|
||||||
#include <__concepts/common_reference_with.h>
|
#include <__concepts/common_reference_with.h>
|
||||||
|
#include <__concepts/comparison_common_type.h>
|
||||||
#include <__concepts/equality_comparable.h>
|
#include <__concepts/equality_comparable.h>
|
||||||
#include <__concepts/same_as.h>
|
#include <__concepts/same_as.h>
|
||||||
#include <__concepts/totally_ordered.h>
|
#include <__concepts/totally_ordered.h>
|
||||||
@@ -39,8 +40,7 @@ concept three_way_comparable =
|
|||||||
|
|
||||||
template <class _Tp, class _Up, class _Cat = partial_ordering>
|
template <class _Tp, class _Up, class _Cat = partial_ordering>
|
||||||
concept three_way_comparable_with =
|
concept three_way_comparable_with =
|
||||||
three_way_comparable<_Tp, _Cat> && three_way_comparable<_Up, _Cat> &&
|
three_way_comparable<_Tp, _Cat> && three_way_comparable<_Up, _Cat> && __comparison_common_type_with<_Tp, _Up> &&
|
||||||
common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> &&
|
|
||||||
three_way_comparable<common_reference_t<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>>, _Cat> &&
|
three_way_comparable<common_reference_t<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>>, _Cat> &&
|
||||||
__weakly_equality_comparable_with<_Tp, _Up> && __partially_ordered_with<_Tp, _Up> &&
|
__weakly_equality_comparable_with<_Tp, _Up> && __partially_ordered_with<_Tp, _Up> &&
|
||||||
requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
|
requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef _LIBCPP___CONCEPTS_COMPARISON_COMMON_TYPE_H
|
||||||
|
#define _LIBCPP___CONCEPTS_COMPARISON_COMMON_TYPE_H
|
||||||
|
|
||||||
|
#include <__concepts/convertible_to.h>
|
||||||
|
#include <__concepts/same_as.h>
|
||||||
|
#include <__config>
|
||||||
|
#include <__type_traits/common_reference.h>
|
||||||
|
#include <__type_traits/remove_cvref.h>
|
||||||
|
|
||||||
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
|
# pragma GCC system_header
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
|
#if _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
|
template <class _Tp, class _Up, class _CommonRef = common_reference_t<const _Tp&, const _Up&>>
|
||||||
|
concept __comparison_common_type_with_impl =
|
||||||
|
same_as<common_reference_t<const _Tp&, const _Up&>, common_reference_t<const _Up&, const _Tp&>> && requires {
|
||||||
|
requires convertible_to<const _Tp&, const _CommonRef&> || convertible_to<_Tp, const _CommonRef&>;
|
||||||
|
requires convertible_to<const _Up&, const _CommonRef&> || convertible_to<_Up, const _CommonRef&>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Tp, class _Up>
|
||||||
|
concept __comparison_common_type_with = __comparison_common_type_with_impl<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
|
||||||
|
|
||||||
|
#endif // _LIBCPP_STD_VER >= 20
|
||||||
|
|
||||||
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
|
#endif // _LIBCPP___CONCEPTS_COMPARISON_COMMON_TYPE_H
|
||||||
+2
-1
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <__concepts/boolean_testable.h>
|
#include <__concepts/boolean_testable.h>
|
||||||
#include <__concepts/common_reference_with.h>
|
#include <__concepts/common_reference_with.h>
|
||||||
|
#include <__concepts/comparison_common_type.h>
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__type_traits/common_reference.h>
|
#include <__type_traits/common_reference.h>
|
||||||
#include <__type_traits/make_const_lvalue_ref.h>
|
#include <__type_traits/make_const_lvalue_ref.h>
|
||||||
@@ -41,7 +42,7 @@ concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>;
|
|||||||
template <class _Tp, class _Up>
|
template <class _Tp, class _Up>
|
||||||
concept equality_comparable_with =
|
concept equality_comparable_with =
|
||||||
equality_comparable<_Tp> && equality_comparable<_Up> &&
|
equality_comparable<_Tp> && equality_comparable<_Up> &&
|
||||||
common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> &&
|
__comparison_common_type_with<_Tp, _Up> &&
|
||||||
equality_comparable<
|
equality_comparable<
|
||||||
common_reference_t<
|
common_reference_t<
|
||||||
__make_const_lvalue_ref<_Tp>,
|
__make_const_lvalue_ref<_Tp>,
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ public:
|
|||||||
wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred);
|
wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred);
|
||||||
|
|
||||||
typedef __libcpp_condvar_t* native_handle_type;
|
typedef __libcpp_condvar_t* native_handle_type;
|
||||||
_LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void
|
void
|
||||||
|
|||||||
Vendored
+63
-280
@@ -14,6 +14,8 @@
|
|||||||
#include <__configuration/abi.h>
|
#include <__configuration/abi.h>
|
||||||
#include <__configuration/availability.h>
|
#include <__configuration/availability.h>
|
||||||
#include <__configuration/compiler.h>
|
#include <__configuration/compiler.h>
|
||||||
|
#include <__configuration/experimental.h>
|
||||||
|
#include <__configuration/hardening.h>
|
||||||
#include <__configuration/language.h>
|
#include <__configuration/language.h>
|
||||||
#include <__configuration/platform.h>
|
#include <__configuration/platform.h>
|
||||||
|
|
||||||
@@ -28,7 +30,7 @@
|
|||||||
// _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM.
|
// _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM.
|
||||||
// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is
|
// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is
|
||||||
// defined to XXYYZZ.
|
// defined to XXYYZZ.
|
||||||
# define _LIBCPP_VERSION 210100
|
# define _LIBCPP_VERSION 220104
|
||||||
|
|
||||||
# define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
|
# define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
|
||||||
# define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)
|
# define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)
|
||||||
@@ -38,195 +40,6 @@
|
|||||||
# define _LIBCPP_FREESTANDING
|
# define _LIBCPP_FREESTANDING
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
// NOLINTNEXTLINE(libcpp-cpp-version-check)
|
|
||||||
# if __cplusplus < 201103L
|
|
||||||
# define _LIBCPP_CXX03_LANG
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if __has_feature(experimental_library)
|
|
||||||
# ifndef _LIBCPP_ENABLE_EXPERIMENTAL
|
|
||||||
# define _LIBCPP_ENABLE_EXPERIMENTAL
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// Incomplete features get their own specific disabling flags. This makes it
|
|
||||||
// easier to grep for target specific flags once the feature is complete.
|
|
||||||
# if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY)
|
|
||||||
# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
|
|
||||||
# define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
|
|
||||||
# define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
|
|
||||||
# define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
|
|
||||||
|
|
||||||
// HARDENING {
|
|
||||||
|
|
||||||
// TODO(LLVM 23): Remove this. We're making these an error to catch folks who might not have migrated.
|
|
||||||
// Since hardening went through several changes (many of which impacted user-facing macros),
|
|
||||||
// we're keeping these checks around for a bit longer than usual. Failure to properly configure
|
|
||||||
// hardening results in checks being dropped silently, which is a pretty big deal.
|
|
||||||
# if defined(_LIBCPP_ENABLE_ASSERTIONS)
|
|
||||||
# error "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
|
|
||||||
# endif
|
|
||||||
# if defined(_LIBCPP_ENABLE_HARDENED_MODE)
|
|
||||||
# error "_LIBCPP_ENABLE_HARDENED_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
|
|
||||||
# endif
|
|
||||||
# if defined(_LIBCPP_ENABLE_SAFE_MODE)
|
|
||||||
# error "_LIBCPP_ENABLE_SAFE_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
|
|
||||||
# endif
|
|
||||||
# if defined(_LIBCPP_ENABLE_DEBUG_MODE)
|
|
||||||
# error "_LIBCPP_ENABLE_DEBUG_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values:
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_HARDENING_MODE_NONE`;
|
|
||||||
// - `_LIBCPP_HARDENING_MODE_FAST`;
|
|
||||||
// - `_LIBCPP_HARDENING_MODE_EXTENSIVE`;
|
|
||||||
// - `_LIBCPP_HARDENING_MODE_DEBUG`.
|
|
||||||
//
|
|
||||||
// These values have the following effects:
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_HARDENING_MODE_NONE` -- sets the hardening mode to "none" which disables all runtime hardening checks;
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_HARDENING_MODE_FAST` -- sets that hardening mode to "fast". The fast mode enables security-critical checks
|
|
||||||
// that can be done with relatively little runtime overhead in constant time;
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_HARDENING_MODE_EXTENSIVE` -- sets the hardening mode to "extensive". The extensive mode is a superset of
|
|
||||||
// the fast mode that additionally enables checks that are relatively cheap and prevent common types of logic errors
|
|
||||||
// but are not necessarily security-critical;
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_HARDENING_MODE_DEBUG` -- sets the hardening mode to "debug". The debug mode is a superset of the extensive
|
|
||||||
// mode and enables all checks available in the library, including internal assertions. Checks that are part of the
|
|
||||||
// debug mode can be very expensive and thus the debug mode is intended to be used for testing, not in production.
|
|
||||||
|
|
||||||
// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These
|
|
||||||
// macros are only for internal use -- users should only pick one of the high-level hardening modes described above.
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and
|
|
||||||
// a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid:
|
|
||||||
// - the sentinel is reachable from the begin iterator;
|
|
||||||
// - TODO(hardening): both iterators refer to the same container.
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through
|
|
||||||
// the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access
|
|
||||||
// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like
|
|
||||||
// `optional` and `function` are considered one-element containers for the purposes of this check.
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_ASSERT_NON_NULL` -- checks that the pointer being dereferenced is not null. On most modern platforms zero
|
|
||||||
// address does not refer to an actual location in memory, so a null pointer dereference would not compromize the
|
|
||||||
// memory security of a program (however, it is still undefined behavior that can result in strange errors due to
|
|
||||||
// compiler optimizations).
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the
|
|
||||||
// given ranges do not overlap.
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_ASSERT_VALID_DEALLOCATION` -- checks that an attempt to deallocate memory is valid (e.g. the given object
|
|
||||||
// was allocated by the given allocator). Violating this category typically results in a memory leak.
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL` -- checks that a call to an external API doesn't fail in
|
|
||||||
// an unexpected manner. This includes triggering documented cases of undefined behavior in an external library (like
|
|
||||||
// attempting to unlock an unlocked mutex in pthreads). Any API external to the library falls under this category
|
|
||||||
// (from system calls to compiler intrinsics). We generally don't expect these failures to compromize memory safety or
|
|
||||||
// otherwise create an immediate security issue.
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure
|
|
||||||
// the containers have compatible allocators.
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN` -- checks that the given argument is within the domain of valid arguments
|
|
||||||
// for the function. Violating this typically produces an incorrect result (e.g. the clamp algorithm returns the
|
|
||||||
// original value without clamping it due to incorrect functors) or puts an object into an invalid state (e.g.
|
|
||||||
// a string view where only a subset of elements is possible to access). This category is for assertions violating
|
|
||||||
// which doesn't cause any immediate issues in the library -- whatever the consequences are, they will happen in the
|
|
||||||
// user code.
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_ASSERT_PEDANTIC` -- checks prerequisites which are imposed by the Standard, but violating which happens to
|
|
||||||
// be benign in our implementation.
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT` -- checks that the given argument satisfies the semantic requirements imposed
|
|
||||||
// by the Standard. Typically, there is no simple way to completely prove that a semantic requirement is satisfied;
|
|
||||||
// thus, this would often be a heuristic check and it might be quite expensive.
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on
|
|
||||||
// user input.
|
|
||||||
//
|
|
||||||
// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet.
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
# define _LIBCPP_HARDENING_MODE_NONE (1 << 1)
|
|
||||||
# define _LIBCPP_HARDENING_MODE_FAST (1 << 2)
|
|
||||||
# define _LIBCPP_HARDENING_MODE_EXTENSIVE (1 << 4) // Deliberately not ordered.
|
|
||||||
# define _LIBCPP_HARDENING_MODE_DEBUG (1 << 3)
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
# ifndef _LIBCPP_HARDENING_MODE
|
|
||||||
|
|
||||||
# ifndef _LIBCPP_HARDENING_MODE_DEFAULT
|
|
||||||
# error _LIBCPP_HARDENING_MODE_DEFAULT is not defined. This definition should be set at configuration time in the \
|
|
||||||
`__config_site` header, please make sure your installation of libc++ is not broken.
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_NONE && \
|
|
||||||
_LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_FAST && \
|
|
||||||
_LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_EXTENSIVE && \
|
|
||||||
_LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
|
|
||||||
# error _LIBCPP_HARDENING_MODE must be set to one of the following values: \
|
|
||||||
_LIBCPP_HARDENING_MODE_NONE, \
|
|
||||||
_LIBCPP_HARDENING_MODE_FAST, \
|
|
||||||
_LIBCPP_HARDENING_MODE_EXTENSIVE, \
|
|
||||||
_LIBCPP_HARDENING_MODE_DEBUG
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// Hardening assertion semantics generally mirror the evaluation semantics of C++26 Contracts:
|
|
||||||
// - `ignore` evaluates the assertion but doesn't do anything if it fails (note that it differs from the Contracts
|
|
||||||
// `ignore` semantic which wouldn't evaluate the assertion at all);
|
|
||||||
// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution;
|
|
||||||
// - `quick-enforce` terminates the program as fast as possible (via trapping);
|
|
||||||
// - `enforce` logs an error and then terminates the program.
|
|
||||||
//
|
|
||||||
// Notes:
|
|
||||||
// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant
|
|
||||||
// to make adopting hardening easier but should not be used outside of this scenario;
|
|
||||||
// - C++26 wording for Library Hardening precludes a conforming Hardened implementation from using the Contracts
|
|
||||||
// `ignore` semantic when evaluating hardened preconditions in the Library. Libc++ allows using this semantic for
|
|
||||||
// hardened preconditions, however, be aware that using `ignore` does not produce a conforming "Hardened"
|
|
||||||
// implementation, unlike the other semantics above.
|
|
||||||
// clang-format off
|
|
||||||
# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 1)
|
|
||||||
# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 2)
|
|
||||||
# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 3)
|
|
||||||
# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 4)
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
// Allow users to define an arbitrary assertion semantic; otherwise, use the default mapping from modes to semantics.
|
|
||||||
// The default is for production-capable modes to use `quick-enforce` (i.e., trap) and for the `debug` mode to use
|
|
||||||
// `enforce` (i.e., log and abort).
|
|
||||||
# ifndef _LIBCPP_ASSERTION_SEMANTIC
|
|
||||||
|
|
||||||
# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
|
|
||||||
# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# else
|
|
||||||
# if !_LIBCPP_HAS_EXPERIMENTAL_LIBRARY
|
|
||||||
# error "Assertion semantics are an experimental feature."
|
|
||||||
# endif
|
|
||||||
# if defined(_LIBCPP_CXX03_LANG)
|
|
||||||
# error "Assertion semantics are not available in the C++03 mode."
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# endif // _LIBCPP_ASSERTION_SEMANTIC
|
|
||||||
|
|
||||||
// } HARDENING
|
|
||||||
|
|
||||||
# define _LIBCPP_TOSTRING2(x) #x
|
# define _LIBCPP_TOSTRING2(x) #x
|
||||||
# define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
|
# define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
|
||||||
|
|
||||||
@@ -320,13 +133,6 @@ _LIBCPP_HARDENING_MODE_DEBUG
|
|||||||
// When this option is used, the token passed to `std::random_device`'s
|
// When this option is used, the token passed to `std::random_device`'s
|
||||||
// constructor *must* be "/dev/urandom" -- anything else is an error.
|
// constructor *must* be "/dev/urandom" -- anything else is an error.
|
||||||
//
|
//
|
||||||
// _LIBCPP_USING_NACL_RANDOM
|
|
||||||
// NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access,
|
|
||||||
// including accesses to the special files under `/dev`. This implementation
|
|
||||||
// uses the NaCL syscall `nacl_secure_random_init()` to get entropy.
|
|
||||||
// When this option is used, the token passed to `std::random_device`'s
|
|
||||||
// constructor *must* be "/dev/urandom" -- anything else is an error.
|
|
||||||
//
|
|
||||||
// _LIBCPP_USING_WIN32_RANDOM
|
// _LIBCPP_USING_WIN32_RANDOM
|
||||||
// Use rand_s(), for use on Windows.
|
// Use rand_s(), for use on Windows.
|
||||||
// When this option is used, the token passed to `std::random_device`'s
|
// When this option is used, the token passed to `std::random_device`'s
|
||||||
@@ -338,8 +144,6 @@ _LIBCPP_HARDENING_MODE_DEBUG
|
|||||||
# define _LIBCPP_USING_GETENTROPY
|
# define _LIBCPP_USING_GETENTROPY
|
||||||
# elif defined(__Fuchsia__)
|
# elif defined(__Fuchsia__)
|
||||||
# define _LIBCPP_USING_FUCHSIA_CPRNG
|
# define _LIBCPP_USING_FUCHSIA_CPRNG
|
||||||
# elif defined(__native_client__)
|
|
||||||
# define _LIBCPP_USING_NACL_RANDOM
|
|
||||||
# elif defined(_LIBCPP_WIN32API)
|
# elif defined(_LIBCPP_WIN32API)
|
||||||
# define _LIBCPP_USING_WIN32_RANDOM
|
# define _LIBCPP_USING_WIN32_RANDOM
|
||||||
# else
|
# else
|
||||||
@@ -348,7 +152,7 @@ _LIBCPP_HARDENING_MODE_DEBUG
|
|||||||
|
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
|
|
||||||
# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp)
|
# define _LIBCPP_ALIGNOF(...) alignof(__VA_ARGS__)
|
||||||
# define _ALIGNAS_TYPE(x) alignas(x)
|
# define _ALIGNAS_TYPE(x) alignas(x)
|
||||||
# define _ALIGNAS(x) alignas(x)
|
# define _ALIGNAS(x) alignas(x)
|
||||||
# define _NOEXCEPT noexcept
|
# define _NOEXCEPT noexcept
|
||||||
@@ -357,7 +161,7 @@ _LIBCPP_HARDENING_MODE_DEBUG
|
|||||||
|
|
||||||
# else
|
# else
|
||||||
|
|
||||||
# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp)
|
# define _LIBCPP_ALIGNOF(...) _Alignof(__VA_ARGS__)
|
||||||
# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
|
# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
|
||||||
# define _ALIGNAS(x) __attribute__((__aligned__(x)))
|
# define _ALIGNAS(x) __attribute__((__aligned__(x)))
|
||||||
# define nullptr __nullptr
|
# define nullptr __nullptr
|
||||||
@@ -471,6 +275,12 @@ typedef __char32_t char32_t;
|
|||||||
# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
|
# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
// Macros to enter and leave a state where deprecation warnings are suppressed.
|
||||||
|
# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH \
|
||||||
|
_LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated") \
|
||||||
|
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations")
|
||||||
|
# define _LIBCPP_SUPPRESS_DEPRECATED_POP _LIBCPP_DIAGNOSTIC_POP
|
||||||
|
|
||||||
# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
|
# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
|
||||||
# define _LIBCPP_HARDENING_SIG f
|
# define _LIBCPP_HARDENING_SIG f
|
||||||
# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_EXTENSIVE
|
# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_EXTENSIVE
|
||||||
@@ -481,6 +291,16 @@ typedef __char32_t char32_t;
|
|||||||
# define _LIBCPP_HARDENING_SIG n // "none"
|
# define _LIBCPP_HARDENING_SIG n // "none"
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE
|
||||||
|
# define _LIBCPP_ASSERTION_SEMANTIC_SIG o
|
||||||
|
# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
|
||||||
|
# define _LIBCPP_ASSERTION_SEMANTIC_SIG q
|
||||||
|
# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
|
||||||
|
# define _LIBCPP_ASSERTION_SEMANTIC_SIG e
|
||||||
|
# else
|
||||||
|
# define _LIBCPP_ASSERTION_SEMANTIC_SIG i // `ignore`
|
||||||
|
# endif
|
||||||
|
|
||||||
# if !_LIBCPP_HAS_EXCEPTIONS
|
# if !_LIBCPP_HAS_EXCEPTIONS
|
||||||
# define _LIBCPP_EXCEPTIONS_SIG n
|
# define _LIBCPP_EXCEPTIONS_SIG n
|
||||||
# else
|
# else
|
||||||
@@ -488,7 +308,9 @@ typedef __char32_t char32_t;
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
# define _LIBCPP_ODR_SIGNATURE \
|
# define _LIBCPP_ODR_SIGNATURE \
|
||||||
_LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_EXCEPTIONS_SIG), _LIBCPP_VERSION)
|
_LIBCPP_CONCAT( \
|
||||||
|
_LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_ASSERTION_SEMANTIC_SIG), _LIBCPP_EXCEPTIONS_SIG), \
|
||||||
|
_LIBCPP_VERSION)
|
||||||
|
|
||||||
// This macro marks a symbol as being hidden from libc++'s ABI. This is achieved
|
// This macro marks a symbol as being hidden from libc++'s ABI. This is achieved
|
||||||
// on two levels:
|
// on two levels:
|
||||||
@@ -550,16 +372,6 @@ typedef __char32_t char32_t;
|
|||||||
# endif
|
# endif
|
||||||
# define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
|
# define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
|
||||||
|
|
||||||
# ifdef _LIBCPP_BUILDING_LIBRARY
|
|
||||||
# if _LIBCPP_ABI_VERSION > 1
|
|
||||||
# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// Clang modules take a significant compile time hit when pushing and popping diagnostics.
|
// Clang modules take a significant compile time hit when pushing and popping diagnostics.
|
||||||
// Since all the headers are marked as system headers unless _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER is defined, we can
|
// Since all the headers are marked as system headers unless _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER is defined, we can
|
||||||
// simply disable this pushing and popping when _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER isn't defined.
|
// simply disable this pushing and popping when _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER isn't defined.
|
||||||
@@ -676,27 +488,6 @@ typedef __char32_t char32_t;
|
|||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
// It is not yet possible to use aligned_alloc() on all Apple platforms since
|
|
||||||
// 10.15 was the first version to ship an implementation of aligned_alloc().
|
|
||||||
# if defined(__APPLE__)
|
|
||||||
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
|
|
||||||
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \
|
|
||||||
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
|
|
||||||
__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
|
|
||||||
(defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \
|
|
||||||
__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000) || \
|
|
||||||
(defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000)
|
|
||||||
# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 0
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 1
|
|
||||||
# endif
|
|
||||||
# elif defined(__ANDROID__) && __ANDROID_API__ < 28
|
|
||||||
// Android only provides aligned_alloc when targeting API 28 or higher.
|
|
||||||
# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 0
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 1
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if defined(__APPLE__) || defined(__FreeBSD__)
|
# if defined(__APPLE__) || defined(__FreeBSD__)
|
||||||
# define _LIBCPP_WCTYPE_IS_MASK
|
# define _LIBCPP_WCTYPE_IS_MASK
|
||||||
# endif
|
# endif
|
||||||
@@ -727,6 +518,15 @@ typedef __char32_t char32_t;
|
|||||||
# define _LIBCPP_DEPRECATED_(m)
|
# define _LIBCPP_DEPRECATED_(m)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be
|
||||||
|
// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that
|
||||||
|
// allows suppression in system headers.
|
||||||
|
# if defined(__DEPRECATED) && __DEPRECATED && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && 0
|
||||||
|
# define _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS 1
|
||||||
|
# else
|
||||||
|
# define _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS 0
|
||||||
|
# endif
|
||||||
|
|
||||||
# if !defined(_LIBCPP_CXX03_LANG)
|
# if !defined(_LIBCPP_CXX03_LANG)
|
||||||
# define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED
|
# define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED
|
||||||
# else
|
# else
|
||||||
@@ -771,17 +571,6 @@ typedef __char32_t char32_t;
|
|||||||
# define _LIBCPP_DEPRECATED_WITH_CHAR8_T
|
# define _LIBCPP_DEPRECATED_WITH_CHAR8_T
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
// Macros to enter and leave a state where deprecation warnings are suppressed.
|
|
||||||
# if defined(_LIBCPP_COMPILER_CLANG_BASED) || defined(_LIBCPP_COMPILER_GCC)
|
|
||||||
# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH \
|
|
||||||
_Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wdeprecated\"") \
|
|
||||||
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
|
|
||||||
# define _LIBCPP_SUPPRESS_DEPRECATED_POP _Pragma("GCC diagnostic pop")
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH
|
|
||||||
# define _LIBCPP_SUPPRESS_DEPRECATED_POP
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if _LIBCPP_STD_VER <= 11
|
# if _LIBCPP_STD_VER <= 11
|
||||||
# define _LIBCPP_EXPLICIT_SINCE_CXX14
|
# define _LIBCPP_EXPLICIT_SINCE_CXX14
|
||||||
# else
|
# else
|
||||||
@@ -861,18 +650,10 @@ typedef __char32_t char32_t;
|
|||||||
# endif // _LIBCPP_HAS_THREAD_API
|
# endif // _LIBCPP_HAS_THREAD_API
|
||||||
# endif // _LIBCPP_HAS_THREADS
|
# endif // _LIBCPP_HAS_THREADS
|
||||||
|
|
||||||
# if _LIBCPP_HAS_THREAD_API_PTHREAD
|
# if !_LIBCPP_HAS_THREAD_API_PTHREAD
|
||||||
# if defined(__ANDROID__) && __ANDROID_API__ >= 30
|
# define _LIBCPP_HAS_COND_CLOCKWAIT 0
|
||||||
# define _LIBCPP_HAS_COND_CLOCKWAIT 1
|
# elif (defined(__ANDROID__) && __ANDROID_API__ >= 30) || _LIBCPP_GLIBC_PREREQ(2, 30)
|
||||||
# elif defined(_LIBCPP_GLIBC_PREREQ)
|
# define _LIBCPP_HAS_COND_CLOCKWAIT 1
|
||||||
# if _LIBCPP_GLIBC_PREREQ(2, 30)
|
|
||||||
# define _LIBCPP_HAS_COND_CLOCKWAIT 1
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_HAS_COND_CLOCKWAIT 0
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_HAS_COND_CLOCKWAIT 0
|
|
||||||
# endif
|
|
||||||
# else
|
# else
|
||||||
# define _LIBCPP_HAS_COND_CLOCKWAIT 0
|
# define _LIBCPP_HAS_COND_CLOCKWAIT 0
|
||||||
# endif
|
# endif
|
||||||
@@ -951,8 +732,8 @@ typedef __char32_t char32_t;
|
|||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(__no_thread_safety_analysis__)
|
# if __has_cpp_attribute(_Clang::__no_thread_safety_analysis__)
|
||||||
# define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((__no_thread_safety_analysis__))
|
# define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS [[_Clang::__no_thread_safety_analysis__]]
|
||||||
# else
|
# else
|
||||||
# define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
|
# define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
|
||||||
# endif
|
# endif
|
||||||
@@ -1038,12 +819,8 @@ typedef __char32_t char32_t;
|
|||||||
// the latter depends on internal GNU libc details that are not appropriate
|
// the latter depends on internal GNU libc details that are not appropriate
|
||||||
// to depend on here, so any declarations present when __cpp_char8_t is not
|
// to depend on here, so any declarations present when __cpp_char8_t is not
|
||||||
// defined are ignored.
|
// defined are ignored.
|
||||||
# if defined(_LIBCPP_GLIBC_PREREQ)
|
# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t)
|
||||||
# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t)
|
# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
|
||||||
# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
|
|
||||||
# endif
|
|
||||||
# else
|
# else
|
||||||
# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
|
# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
|
||||||
# endif
|
# endif
|
||||||
@@ -1067,8 +844,7 @@ typedef __char32_t char32_t;
|
|||||||
# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "")
|
# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "")
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
// TODO(LLVM 22): Remove the workaround
|
# if defined(__OBJC__) && defined(_LIBCPP_APPLE_CLANG_VER)
|
||||||
# if defined(__OBJC__) && (!defined(_LIBCPP_CLANG_VER) || _LIBCPP_CLANG_VER < 2001)
|
|
||||||
# define _LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS
|
# define _LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@@ -1153,12 +929,33 @@ typedef __char32_t char32_t;
|
|||||||
# define _LIBCPP_DIAGNOSE_WARNING(...)
|
# define _LIBCPP_DIAGNOSE_WARNING(...)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if __has_attribute(__diagnose_if__) && !defined(_LIBCPP_APPLE_CLANG_VER) && \
|
||||||
|
(!defined(_LIBCPP_CLANG_VER) || _LIBCPP_CLANG_VER >= 2001)
|
||||||
|
# define _LIBCPP_DIAGNOSE_IF(...) __attribute__((__diagnose_if__(__VA_ARGS__)))
|
||||||
|
# else
|
||||||
|
# define _LIBCPP_DIAGNOSE_IF(...)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define _LIBCPP_DIAGNOSE_NULLPTR_IF(condition, condition_description) \
|
||||||
|
_LIBCPP_DIAGNOSE_IF( \
|
||||||
|
condition, \
|
||||||
|
"null passed to callee that requires a non-null argument" condition_description, \
|
||||||
|
"warning", \
|
||||||
|
"nonnull")
|
||||||
|
|
||||||
# if __has_cpp_attribute(_Clang::__lifetimebound__)
|
# if __has_cpp_attribute(_Clang::__lifetimebound__)
|
||||||
# define _LIBCPP_LIFETIMEBOUND [[_Clang::__lifetimebound__]]
|
# define _LIBCPP_LIFETIMEBOUND [[_Clang::__lifetimebound__]]
|
||||||
# else
|
# else
|
||||||
# define _LIBCPP_LIFETIMEBOUND
|
# define _LIBCPP_LIFETIMEBOUND
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
// This is to work around https://llvm.org/PR156809
|
||||||
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
|
# define _LIBCPP_CTOR_LIFETIMEBOUND _LIBCPP_LIFETIMEBOUND
|
||||||
|
# else
|
||||||
|
# define _LIBCPP_CTOR_LIFETIMEBOUND
|
||||||
|
# endif
|
||||||
|
|
||||||
# if __has_cpp_attribute(_Clang::__noescape__)
|
# if __has_cpp_attribute(_Clang::__noescape__)
|
||||||
# define _LIBCPP_NOESCAPE [[_Clang::__noescape__]]
|
# define _LIBCPP_NOESCAPE [[_Clang::__noescape__]]
|
||||||
# else
|
# else
|
||||||
@@ -1172,12 +969,6 @@ typedef __char32_t char32_t;
|
|||||||
# define _LIBCPP_NO_SPECIALIZATIONS
|
# define _LIBCPP_NO_SPECIALIZATIONS
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# if __has_cpp_attribute(_Clang::__standalone_debug__)
|
|
||||||
# define _LIBCPP_STANDALONE_DEBUG [[_Clang::__standalone_debug__]]
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_STANDALONE_DEBUG
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if __has_cpp_attribute(_Clang::__preferred_name__)
|
# if __has_cpp_attribute(_Clang::__preferred_name__)
|
||||||
# define _LIBCPP_PREFERRED_NAME(x) [[_Clang::__preferred_name__(x)]]
|
# define _LIBCPP_PREFERRED_NAME(x) [[_Clang::__preferred_name__(x)]]
|
||||||
# else
|
# else
|
||||||
@@ -1257,14 +1048,6 @@ typedef __char32_t char32_t;
|
|||||||
# define _LIBCPP_DIAGNOSE_NULLPTR
|
# define _LIBCPP_DIAGNOSE_NULLPTR
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
// TODO(LLVM 22): Remove this macro once LLVM19 support ends. __cpp_explicit_this_parameter has been set in LLVM20.
|
|
||||||
// Clang-18 has support for deducing this, but it does not set the FTM.
|
|
||||||
# if defined(__cpp_explicit_this_parameter) || (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1800)
|
|
||||||
# define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 1
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 0
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif // _LIBCPP___CONFIG
|
#endif // _LIBCPP___CONFIG
|
||||||
|
|||||||
+14
-24
@@ -61,19 +61,9 @@
|
|||||||
// According to the Standard, `bitset::operator[] const` returns bool
|
// According to the Standard, `bitset::operator[] const` returns bool
|
||||||
# define _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
|
# define _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
|
||||||
|
|
||||||
// In LLVM 20, we've changed to take these ABI breaks unconditionally. These flags only exist in case someone is running
|
|
||||||
// into the static_asserts we added to catch the ABI break and don't care that it is one.
|
|
||||||
// TODO(LLVM 22): Remove these flags
|
|
||||||
# define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB
|
|
||||||
# define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB
|
|
||||||
# define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB
|
|
||||||
# define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB
|
|
||||||
|
|
||||||
// These flags are documented in ABIGuarantees.rst
|
// These flags are documented in ABIGuarantees.rst
|
||||||
# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
|
# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
|
||||||
# define _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON
|
# define _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
|
||||||
# define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
|
|
||||||
# define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
|
|
||||||
# define _LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI
|
# define _LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI
|
||||||
# define _LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI
|
# define _LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI
|
||||||
# define _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION
|
# define _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION
|
||||||
@@ -84,25 +74,16 @@
|
|||||||
# define _LIBCPP_ABI_NO_FILESYSTEM_INLINE_NAMESPACE
|
# define _LIBCPP_ABI_NO_FILESYSTEM_INLINE_NAMESPACE
|
||||||
# define _LIBCPP_ABI_NO_ITERATOR_BASES
|
# define _LIBCPP_ABI_NO_ITERATOR_BASES
|
||||||
# define _LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT
|
# define _LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT
|
||||||
|
# define _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER
|
||||||
# define _LIBCPP_ABI_OPTIMIZED_FUNCTION
|
# define _LIBCPP_ABI_OPTIMIZED_FUNCTION
|
||||||
# define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
|
# define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
|
||||||
# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
|
# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
|
||||||
# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY
|
# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY
|
||||||
# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW
|
# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW
|
||||||
# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
|
# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
|
||||||
|
# define _LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR
|
||||||
|
|
||||||
#elif _LIBCPP_ABI_VERSION == 1
|
#elif _LIBCPP_ABI_VERSION == 1
|
||||||
# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
|
|
||||||
// Enable compiling copies of now inline methods into the dylib to support
|
|
||||||
// applications compiled against older libraries. This is unnecessary with
|
|
||||||
// COFF dllexport semantics, since dllexport forces a non-inline definition
|
|
||||||
// of inline functions to be emitted anyway. Our own non-inline copy would
|
|
||||||
// conflict with the dllexport-emitted copy, so we disable it. For XCOFF,
|
|
||||||
// the linker will take issue with the symbols in the shared object if the
|
|
||||||
// weak inline methods get visibility (such as from -fvisibility-inlines-hidden),
|
|
||||||
// so disable it.
|
|
||||||
# define _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS
|
|
||||||
# endif
|
|
||||||
// Feature macros for disabling pre ABI v1 features. All of these options
|
// Feature macros for disabling pre ABI v1 features. All of these options
|
||||||
// are deprecated.
|
// are deprecated.
|
||||||
# if defined(__FreeBSD__)
|
# if defined(__FreeBSD__)
|
||||||
@@ -110,11 +91,20 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO(LLVM 22): Remove this check
|
||||||
|
#if defined(_LIBCPP_ABI_NO_ITERATOR_BASES) && !defined(_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER)
|
||||||
|
# ifndef _LIBCPP_ONLY_NO_ITERATOR_BASES
|
||||||
|
# error "You probably want to define _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER. This has been split out from" \
|
||||||
|
" _LIBCPP_ABI_NO_ITERATOR_BASES to allow only removing the second iterator member, since they aren't really related." \
|
||||||
|
"If you actually want this ABI configuration, please define _LIBCPP_ONLY_NO_ITERATOR_BASES instead."
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// We had some bugs where we use [[no_unique_address]] together with construct_at,
|
// We had some bugs where we use [[no_unique_address]] together with construct_at,
|
||||||
// which causes UB as the call on construct_at could write to overlapping subobjects
|
// which causes UB as the call on construct_at could write to overlapping subobjects
|
||||||
//
|
//
|
||||||
// https://github.com/llvm/llvm-project/issues/70506
|
// https://llvm.org/PR70506
|
||||||
// https://github.com/llvm/llvm-project/issues/70494
|
// https://llvm.org/PR70494
|
||||||
//
|
//
|
||||||
// To fix the bug we had to change the ABI of some classes to remove [[no_unique_address]] under certain conditions.
|
// To fix the bug we had to change the ABI of some classes to remove [[no_unique_address]] under certain conditions.
|
||||||
// The macro below is used for all classes whose ABI have changed as part of fixing these bugs.
|
// The macro below is used for all classes whose ABI have changed as part of fixing these bugs.
|
||||||
|
|||||||
+65
-118
@@ -17,62 +17,17 @@
|
|||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Libc++ is shipped by various vendors. In particular, it is used as a system
|
// This file defines a framework that can be used by vendors to encode the version of an operating system that various
|
||||||
// library on macOS, iOS and other Apple platforms. In order for users to be
|
// features of libc++ has been shipped in. This is primarily intended to allow safely deploying an executable built with
|
||||||
// able to compile a binary that is intended to be deployed to an older version
|
// a new version of the library on a platform containing an older version of the built library.
|
||||||
// of a platform, Clang provides availability attributes [1]. These attributes
|
// Detailed documentation for this can be found at https://libcxx.llvm.org/VendorDocumentation.html#availability-markup
|
||||||
// can be placed on declarations and are used to describe the life cycle of a
|
|
||||||
// symbol in the library.
|
|
||||||
//
|
|
||||||
// The main goal is to ensure a compile-time error if a symbol that hasn't been
|
|
||||||
// introduced in a previously released library is used in a program that targets
|
|
||||||
// that previously released library. Normally, this would be a load-time error
|
|
||||||
// when one tries to launch the program against the older library.
|
|
||||||
//
|
|
||||||
// For example, the filesystem library was introduced in the dylib in LLVM 9.
|
|
||||||
// On Apple platforms, this corresponds to macOS 10.15. If a user compiles on
|
|
||||||
// a macOS 10.15 host but targets macOS 10.13 with their program, the compiler
|
|
||||||
// would normally not complain (because the required declarations are in the
|
|
||||||
// headers), but the dynamic loader would fail to find the symbols when actually
|
|
||||||
// trying to launch the program on macOS 10.13. To turn this into a compile-time
|
|
||||||
// issue instead, declarations are annotated with when they were introduced, and
|
|
||||||
// the compiler can produce a diagnostic if the program references something that
|
|
||||||
// isn't available on the deployment target.
|
|
||||||
//
|
|
||||||
// This mechanism is general in nature, and any vendor can add their markup to
|
|
||||||
// the library (see below). Whenever a new feature is added that requires support
|
|
||||||
// in the shared library, two macros are added below to allow marking the feature
|
|
||||||
// as unavailable:
|
|
||||||
// 1. A macro named `_LIBCPP_AVAILABILITY_HAS_<feature>` which must be defined
|
|
||||||
// to `_LIBCPP_INTRODUCED_IN_<version>` for the appropriate LLVM version.
|
|
||||||
// 2. A macro named `_LIBCPP_AVAILABILITY_<feature>`, which must be defined to
|
|
||||||
// `_LIBCPP_INTRODUCED_IN_<version>_MARKUP` for the appropriate LLVM version.
|
|
||||||
//
|
|
||||||
// When vendors decide to ship the feature as part of their shared library, they
|
|
||||||
// can update the `_LIBCPP_INTRODUCED_IN_<version>` macro (and the markup counterpart)
|
|
||||||
// based on the platform version they shipped that version of LLVM in. The library
|
|
||||||
// will then use this markup to provide an optimal user experience on these platforms.
|
|
||||||
//
|
|
||||||
// Furthermore, many features in the standard library have corresponding
|
|
||||||
// feature-test macros. The `_LIBCPP_AVAILABILITY_HAS_<feature>` macros
|
|
||||||
// are checked by the corresponding feature-test macros generated by
|
|
||||||
// generate_feature_test_macro_components.py to ensure that the library
|
|
||||||
// doesn't announce a feature as being implemented if it is unavailable on
|
|
||||||
// the deployment target.
|
|
||||||
//
|
|
||||||
// Note that this mechanism is disabled by default in the "upstream" libc++.
|
|
||||||
// Availability annotations are only meaningful when shipping libc++ inside
|
|
||||||
// a platform (i.e. as a system library), and so vendors that want them should
|
|
||||||
// turn those annotations on at CMake configuration time.
|
|
||||||
//
|
|
||||||
// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability
|
|
||||||
|
|
||||||
// Availability markup is disabled when building the library, or when a non-Clang
|
// Availability markup is disabled when building the library, or when a non-Clang
|
||||||
// compiler is used because only Clang supports the necessary attributes.
|
// compiler is used because only Clang supports the necessary attributes.
|
||||||
//
|
//
|
||||||
// We also allow users to force-disable availability markup via the `_LIBCPP_DISABLE_AVAILABILITY`
|
// We also allow users to force-disable availability markup via the `_LIBCPP_DISABLE_AVAILABILITY`
|
||||||
// macro because that is the only way to work around a Clang bug related to availability
|
// macro because that is the only way to work around a Clang bug related to availability
|
||||||
// attributes: https://github.com/llvm/llvm-project/issues/134151.
|
// attributes: https://llvm.org/PR134151.
|
||||||
// Once that bug has been fixed, we should remove the macro.
|
// Once that bug has been fixed, we should remove the macro.
|
||||||
#if defined(_LIBCPP_BUILDING_LIBRARY) || defined(_LIBCXXABI_BUILDING_LIBRARY) || \
|
#if defined(_LIBCPP_BUILDING_LIBRARY) || defined(_LIBCXXABI_BUILDING_LIBRARY) || \
|
||||||
!defined(_LIBCPP_COMPILER_CLANG_BASED) || defined(_LIBCPP_DISABLE_AVAILABILITY)
|
!defined(_LIBCPP_COMPILER_CLANG_BASED) || defined(_LIBCPP_DISABLE_AVAILABILITY)
|
||||||
@@ -84,6 +39,9 @@
|
|||||||
// in all versions of the library are available.
|
// in all versions of the library are available.
|
||||||
#if !_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS
|
#if !_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS
|
||||||
|
|
||||||
|
# define _LIBCPP_INTRODUCED_IN_LLVM_22 1
|
||||||
|
# define _LIBCPP_INTRODUCED_IN_LLVM_22_ATTRIBUTE /* nothing */
|
||||||
|
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_21 1
|
# define _LIBCPP_INTRODUCED_IN_LLVM_21 1
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE /* nothing */
|
# define _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE /* nothing */
|
||||||
|
|
||||||
@@ -108,32 +66,55 @@
|
|||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_12 1
|
# define _LIBCPP_INTRODUCED_IN_LLVM_12 1
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_12_ATTRIBUTE /* nothing */
|
# define _LIBCPP_INTRODUCED_IN_LLVM_12_ATTRIBUTE /* nothing */
|
||||||
|
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_11 1
|
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_11_ATTRIBUTE /* nothing */
|
|
||||||
|
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_9 1
|
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE /* nothing */
|
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_PUSH /* nothing */
|
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_POP /* nothing */
|
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
|
// LLVM 22
|
||||||
|
// TODO: Fill this in
|
||||||
|
# define _LIBCPP_INTRODUCED_IN_LLVM_22 0
|
||||||
|
# define _LIBCPP_INTRODUCED_IN_LLVM_22_ATTRIBUTE __attribute__((unavailable))
|
||||||
|
|
||||||
// LLVM 21
|
// LLVM 21
|
||||||
// TODO: Fill this in
|
// TODO: Fill this in
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_21 0
|
# define _LIBCPP_INTRODUCED_IN_LLVM_21 0
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE __attribute__((unavailable))
|
# define _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE __attribute__((unavailable))
|
||||||
|
|
||||||
// LLVM 20
|
// LLVM 20
|
||||||
// TODO: Fill this in
|
//
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_20 0
|
// Note that versions for most Apple OSes were bumped forward and aligned in that release.
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_20_ATTRIBUTE __attribute__((unavailable))
|
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 260000) || \
|
||||||
|
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 260000) || \
|
||||||
|
(defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 260000) || \
|
||||||
|
(defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 260000) || \
|
||||||
|
(defined(__ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__ < 100000)
|
||||||
|
# define _LIBCPP_INTRODUCED_IN_LLVM_20 0
|
||||||
|
# else
|
||||||
|
# define _LIBCPP_INTRODUCED_IN_LLVM_20 1
|
||||||
|
# endif
|
||||||
|
# define _LIBCPP_INTRODUCED_IN_LLVM_20_ATTRIBUTE \
|
||||||
|
__attribute__((availability(macos, strict, introduced = 26.0))) \
|
||||||
|
__attribute__((availability(ios, strict, introduced = 26.0))) \
|
||||||
|
__attribute__((availability(tvos, strict, introduced = 26.0))) \
|
||||||
|
__attribute__((availability(watchos, strict, introduced = 26.0))) \
|
||||||
|
__attribute__((availability(bridgeos, strict, introduced = 10.0)))
|
||||||
|
|
||||||
// LLVM 19
|
// LLVM 19
|
||||||
// TODO: Fill this in
|
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 150400) || \
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_19 0
|
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 180400) || \
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_19_ATTRIBUTE __attribute__((unavailable))
|
(defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 180400) || \
|
||||||
|
(defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 110400) || \
|
||||||
|
(defined(__ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__ < 90400)
|
||||||
|
# define _LIBCPP_INTRODUCED_IN_LLVM_19 0
|
||||||
|
# else
|
||||||
|
# define _LIBCPP_INTRODUCED_IN_LLVM_19 1
|
||||||
|
# endif
|
||||||
|
# define _LIBCPP_INTRODUCED_IN_LLVM_19_ATTRIBUTE \
|
||||||
|
__attribute__((availability(macos, strict, introduced = 15.4))) \
|
||||||
|
__attribute__((availability(ios, strict, introduced = 18.4))) \
|
||||||
|
__attribute__((availability(tvos, strict, introduced = 18.4))) \
|
||||||
|
__attribute__((availability(watchos, strict, introduced = 11.4))) \
|
||||||
|
__attribute__((availability(bridgeos, strict, introduced = 9.4)))
|
||||||
|
|
||||||
// LLVM 18
|
// LLVM 18
|
||||||
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 150000) || \
|
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 150000) || \
|
||||||
@@ -215,47 +196,13 @@
|
|||||||
__attribute__((availability(bridgeos, strict, introduced = 6.0))) \
|
__attribute__((availability(bridgeos, strict, introduced = 6.0))) \
|
||||||
__attribute__((availability(driverkit, strict, introduced = 21.3)))
|
__attribute__((availability(driverkit, strict, introduced = 21.3)))
|
||||||
|
|
||||||
// LLVM 11
|
# 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__ < 150000) || \
|
||||||
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \
|
(defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 150000) || \
|
||||||
(defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 140000) || \
|
(defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 80000) || \
|
||||||
(defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 70000)
|
(defined(__ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__ < 200000)
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_11 0
|
# warning "The selected platform is no longer supported by libc++."
|
||||||
# else
|
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_11 1
|
|
||||||
# endif
|
# endif
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_11_ATTRIBUTE \
|
|
||||||
__attribute__((availability(macos, strict, introduced = 11.0))) \
|
|
||||||
__attribute__((availability(ios, strict, introduced = 14.0))) \
|
|
||||||
__attribute__((availability(tvos, strict, introduced = 14.0))) \
|
|
||||||
__attribute__((availability(watchos, strict, introduced = 7.0)))
|
|
||||||
|
|
||||||
// LLVM 9
|
|
||||||
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \
|
|
||||||
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
|
|
||||||
(defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) || \
|
|
||||||
(defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000)
|
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_9 0
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_9 1
|
|
||||||
# endif
|
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE \
|
|
||||||
__attribute__((availability(macos, strict, introduced = 10.15))) \
|
|
||||||
__attribute__((availability(ios, strict, introduced = 13.0))) \
|
|
||||||
__attribute__((availability(tvos, strict, introduced = 13.0))) \
|
|
||||||
__attribute__((availability(watchos, strict, introduced = 6.0)))
|
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_PUSH \
|
|
||||||
_Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \
|
|
||||||
_Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \
|
|
||||||
_Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \
|
|
||||||
_Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))")
|
|
||||||
# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_POP \
|
|
||||||
_Pragma("clang attribute pop") \
|
|
||||||
_Pragma("clang attribute pop") \
|
|
||||||
_Pragma("clang attribute pop") \
|
|
||||||
_Pragma("clang attribute pop")
|
|
||||||
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -266,19 +213,12 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// These macros control the availability of all parts of <filesystem> that
|
// This controls the availability of new implementation of std::atomic's
|
||||||
// depend on something in the dylib.
|
// wait, notify_one and notify_all. The new implementation uses
|
||||||
#define _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY _LIBCPP_INTRODUCED_IN_LLVM_9
|
// the native atomic wait/notify operations on platforms that support them
|
||||||
#define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE
|
// based on the size of the atomic type, instead of the type itself.
|
||||||
#define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_PUSH
|
#define _LIBCPP_AVAILABILITY_HAS_NEW_SYNC _LIBCPP_INTRODUCED_IN_LLVM_22
|
||||||
#define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_POP
|
#define _LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_INTRODUCED_IN_LLVM_22_ATTRIBUTE
|
||||||
|
|
||||||
// This controls the availability of the C++20 synchronization library,
|
|
||||||
// which requires shared library support for various operations
|
|
||||||
// (see libcxx/src/atomic.cpp). This includes <barier>, <latch>,
|
|
||||||
// <semaphore>, and notification functions on std::atomic.
|
|
||||||
#define _LIBCPP_AVAILABILITY_HAS_SYNC _LIBCPP_INTRODUCED_IN_LLVM_11
|
|
||||||
#define _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INTRODUCED_IN_LLVM_11_ATTRIBUTE
|
|
||||||
|
|
||||||
// Enable additional explicit instantiations of iostreams components. This
|
// Enable additional explicit instantiations of iostreams components. This
|
||||||
// reduces the number of weak definitions generated in programs that use
|
// reduces the number of weak definitions generated in programs that use
|
||||||
@@ -307,7 +247,7 @@
|
|||||||
// This controls the availability of the C++17 std::pmr library,
|
// This controls the availability of the C++17 std::pmr library,
|
||||||
// which is implemented in large part in the built library.
|
// which is implemented in large part in the built library.
|
||||||
//
|
//
|
||||||
// TODO: Enable std::pmr markup once https://github.com/llvm/llvm-project/issues/40340 has been fixed
|
// TODO: Enable std::pmr markup once https://llvm.org/PR40340 has been fixed
|
||||||
// Until then, it is possible for folks to try to use `std::pmr` when back-deploying to targets that don't support
|
// Until then, it is possible for folks to try to use `std::pmr` when back-deploying to targets that don't support
|
||||||
// it and it'll be a load-time error, but we don't have a good alternative because the library won't compile if we
|
// it and it'll be a load-time error, but we don't have a good alternative because the library won't compile if we
|
||||||
// use availability annotations until that bug has been fixed.
|
// use availability annotations until that bug has been fixed.
|
||||||
@@ -364,4 +304,11 @@
|
|||||||
# define _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION
|
# define _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Only define a bunch of symbols in the dylib if we need to be compatible with LLVM 7 headers or older
|
||||||
|
# if defined(_LIBCPP_BUILDING_LIBRARY) && _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 8
|
||||||
|
# define _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8
|
||||||
|
# else
|
||||||
|
# define _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 _LIBCPP_HIDE_FROM_ABI
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif // _LIBCPP___CONFIGURATION_AVAILABILITY_H
|
#endif // _LIBCPP___CONFIGURATION_AVAILABILITY_H
|
||||||
|
|||||||
+6
-6
@@ -33,16 +33,16 @@
|
|||||||
// Warn if a compiler version is used that is not supported anymore
|
// Warn if a compiler version is used that is not supported anymore
|
||||||
// LLVM RELEASE Update the minimum compiler versions
|
// LLVM RELEASE Update the minimum compiler versions
|
||||||
# if defined(_LIBCPP_CLANG_VER)
|
# if defined(_LIBCPP_CLANG_VER)
|
||||||
# if _LIBCPP_CLANG_VER < 1900
|
# if _LIBCPP_CLANG_VER < 2001
|
||||||
# warning "Libc++ only supports Clang 19 and later"
|
# warning "Libc++ only supports Clang 20 and later"
|
||||||
# endif
|
# endif
|
||||||
# elif defined(_LIBCPP_APPLE_CLANG_VER)
|
# elif defined(_LIBCPP_APPLE_CLANG_VER)
|
||||||
# if _LIBCPP_APPLE_CLANG_VER < 1500
|
# if _LIBCPP_APPLE_CLANG_VER < 1700
|
||||||
# warning "Libc++ only supports AppleClang 15 and later"
|
# warning "Libc++ only supports AppleClang 26 and later"
|
||||||
# endif
|
# endif
|
||||||
# elif defined(_LIBCPP_GCC_VER)
|
# elif defined(_LIBCPP_GCC_VER)
|
||||||
# if _LIBCPP_GCC_VER < 1400
|
# if _LIBCPP_GCC_VER < 1500
|
||||||
# warning "Libc++ only supports GCC 14 and later"
|
# warning "Libc++ only supports GCC 15 and later"
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef _LIBCPP___CONFIGURATION_EXPERIMENTAL_H
|
||||||
|
#define _LIBCPP___CONFIGURATION_EXPERIMENTAL_H
|
||||||
|
|
||||||
|
/* zig patch: instead of including __config_site, zig adds -D flags when compiling */
|
||||||
|
|
||||||
|
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
|
||||||
|
# pragma GCC system_header
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_feature(experimental_library)
|
||||||
|
# ifndef _LIBCPP_ENABLE_EXPERIMENTAL
|
||||||
|
# define _LIBCPP_ENABLE_EXPERIMENTAL
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Incomplete features get their own specific disabling flags. This makes it
|
||||||
|
// easier to grep for target specific flags once the feature is complete.
|
||||||
|
#if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY)
|
||||||
|
# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1
|
||||||
|
#else
|
||||||
|
# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
|
||||||
|
#define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
|
||||||
|
#define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
|
||||||
|
#define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
|
||||||
|
#define _LIBCPP_HAS_EXPERIMENTAL_OPTIONAL_ITERATOR _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
|
||||||
|
|
||||||
|
#endif // _LIBCPP___CONFIGURATION_EXPERIMENTAL_H
|
||||||
+215
@@ -0,0 +1,215 @@
|
|||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef _LIBCPP___CONFIGURATION_HARDENING_H
|
||||||
|
#define _LIBCPP___CONFIGURATION_HARDENING_H
|
||||||
|
|
||||||
|
/* zig patch: instead of including __config_site, zig adds -D flags when compiling */
|
||||||
|
#include <__configuration/experimental.h>
|
||||||
|
#include <__configuration/language.h>
|
||||||
|
|
||||||
|
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
|
||||||
|
# pragma GCC system_header
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO(LLVM 23): Remove this. We're making these an error to catch folks who might not have migrated.
|
||||||
|
// Since hardening went through several changes (many of which impacted user-facing macros),
|
||||||
|
// we're keeping these checks around for a bit longer than usual. Failure to properly configure
|
||||||
|
// hardening results in checks being dropped silently, which is a pretty big deal.
|
||||||
|
#if defined(_LIBCPP_ENABLE_ASSERTIONS)
|
||||||
|
# error "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
|
||||||
|
#endif
|
||||||
|
#if defined(_LIBCPP_ENABLE_HARDENED_MODE)
|
||||||
|
# error "_LIBCPP_ENABLE_HARDENED_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
|
||||||
|
#endif
|
||||||
|
#if defined(_LIBCPP_ENABLE_SAFE_MODE)
|
||||||
|
# error "_LIBCPP_ENABLE_SAFE_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
|
||||||
|
#endif
|
||||||
|
#if defined(_LIBCPP_ENABLE_DEBUG_MODE)
|
||||||
|
# error "_LIBCPP_ENABLE_DEBUG_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values:
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_HARDENING_MODE_NONE`;
|
||||||
|
// - `_LIBCPP_HARDENING_MODE_FAST`;
|
||||||
|
// - `_LIBCPP_HARDENING_MODE_EXTENSIVE`;
|
||||||
|
// - `_LIBCPP_HARDENING_MODE_DEBUG`.
|
||||||
|
//
|
||||||
|
// These values have the following effects:
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_HARDENING_MODE_NONE` -- sets the hardening mode to "none" which disables all runtime hardening checks;
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_HARDENING_MODE_FAST` -- sets that hardening mode to "fast". The fast mode enables security-critical checks
|
||||||
|
// that can be done with relatively little runtime overhead in constant time;
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_HARDENING_MODE_EXTENSIVE` -- sets the hardening mode to "extensive". The extensive mode is a superset of
|
||||||
|
// the fast mode that additionally enables checks that are relatively cheap and prevent common types of logic errors
|
||||||
|
// but are not necessarily security-critical;
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_HARDENING_MODE_DEBUG` -- sets the hardening mode to "debug". The debug mode is a superset of the extensive
|
||||||
|
// mode and enables all checks available in the library, including internal assertions. Checks that are part of the
|
||||||
|
// debug mode can be very expensive and thus the debug mode is intended to be used for testing, not in production.
|
||||||
|
|
||||||
|
// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These
|
||||||
|
// macros are only for internal use -- users should only pick one of the high-level hardening modes described above.
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and
|
||||||
|
// a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid:
|
||||||
|
// - the sentinel is reachable from the begin iterator;
|
||||||
|
// - TODO(hardening): both iterators refer to the same container.
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through
|
||||||
|
// the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access
|
||||||
|
// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like
|
||||||
|
// `optional` and `function` are considered one-element containers for the purposes of this check.
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_ASSERT_NON_NULL` -- checks that the pointer being dereferenced is not null. On most modern platforms zero
|
||||||
|
// address does not refer to an actual location in memory, so a null pointer dereference would not compromize the
|
||||||
|
// memory security of a program (however, it is still undefined behavior that can result in strange errors due to
|
||||||
|
// compiler optimizations).
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the
|
||||||
|
// given ranges do not overlap.
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_ASSERT_VALID_DEALLOCATION` -- checks that an attempt to deallocate memory is valid (e.g. the given object
|
||||||
|
// was allocated by the given allocator). Violating this category typically results in a memory leak.
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL` -- checks that a call to an external API doesn't fail in
|
||||||
|
// an unexpected manner. This includes triggering documented cases of undefined behavior in an external library (like
|
||||||
|
// attempting to unlock an unlocked mutex in pthreads). Any API external to the library falls under this category
|
||||||
|
// (from system calls to compiler intrinsics). We generally don't expect these failures to compromize memory safety or
|
||||||
|
// otherwise create an immediate security issue.
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure
|
||||||
|
// the containers have compatible allocators.
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN` -- checks that the given argument is within the domain of valid arguments
|
||||||
|
// for the function. Violating this typically produces an incorrect result (e.g. the clamp algorithm returns the
|
||||||
|
// original value without clamping it due to incorrect functors) or puts an object into an invalid state (e.g.
|
||||||
|
// a string view where only a subset of elements is possible to access). This category is for assertions violating
|
||||||
|
// which doesn't cause any immediate issues in the library -- whatever the consequences are, they will happen in the
|
||||||
|
// user code.
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_ASSERT_PEDANTIC` -- checks prerequisites which are imposed by the Standard, but violating which happens to
|
||||||
|
// be benign in our implementation.
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT` -- checks that the given argument satisfies the semantic requirements imposed
|
||||||
|
// by the Standard. Typically, there is no simple way to completely prove that a semantic requirement is satisfied;
|
||||||
|
// thus, this would often be a heuristic check and it might be quite expensive.
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on
|
||||||
|
// user input.
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet.
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
# define _LIBCPP_HARDENING_MODE_NONE (1 << 1)
|
||||||
|
# define _LIBCPP_HARDENING_MODE_FAST (1 << 2)
|
||||||
|
# define _LIBCPP_HARDENING_MODE_EXTENSIVE (1 << 4) // Deliberately not ordered.
|
||||||
|
# define _LIBCPP_HARDENING_MODE_DEBUG (1 << 3)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
#ifndef _LIBCPP_HARDENING_MODE
|
||||||
|
|
||||||
|
# ifndef _LIBCPP_HARDENING_MODE_DEFAULT
|
||||||
|
# error _LIBCPP_HARDENING_MODE_DEFAULT is not defined. This definition should be set at configuration time in the \
|
||||||
|
`__config_site` header, please make sure your installation of libc++ is not broken.
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_NONE && _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_FAST && \
|
||||||
|
_LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_EXTENSIVE && \
|
||||||
|
_LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
|
||||||
|
# error _LIBCPP_HARDENING_MODE must be set to one of the following values: \
|
||||||
|
_LIBCPP_HARDENING_MODE_NONE, \
|
||||||
|
_LIBCPP_HARDENING_MODE_FAST, \
|
||||||
|
_LIBCPP_HARDENING_MODE_EXTENSIVE, \
|
||||||
|
_LIBCPP_HARDENING_MODE_DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The library provides the macro `_LIBCPP_ASSERTION_SEMANTIC` for configuring the assertion semantic used by hardening;
|
||||||
|
// it can be set to one of the following values:
|
||||||
|
//
|
||||||
|
// - `_LIBCPP_ASSERTION_SEMANTIC_IGNORE`;
|
||||||
|
// - `_LIBCPP_ASSERTION_SEMANTIC_OBSERVE`;
|
||||||
|
// - `_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE`;
|
||||||
|
// - `_LIBCPP_ASSERTION_SEMANTIC_ENFORCE`.
|
||||||
|
//
|
||||||
|
// libc++ assertion semantics generally mirror the evaluation semantics of C++26 Contracts:
|
||||||
|
// - `ignore` evaluates the assertion but doesn't do anything if it fails (note that it differs from the Contracts
|
||||||
|
// `ignore` semantic which wouldn't evaluate the assertion at all);
|
||||||
|
// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution;
|
||||||
|
// - `quick-enforce` terminates the program as fast as possible (via trapping);
|
||||||
|
// - `enforce` logs an error and then terminates the program.
|
||||||
|
//
|
||||||
|
// Additionally, a special `hardening-dependent` value selects the assertion semantic based on the hardening mode in
|
||||||
|
// effect: the production-capable modes (`fast` and `extensive`) map to `quick_enforce` and the `debug` mode maps to
|
||||||
|
// `enforce`. The `hardening-dependent` semantic cannot be selected explicitly, it is only used when no assertion
|
||||||
|
// semantic is provided by the user _and_ the library's default semantic is configured to be dependent on hardening.
|
||||||
|
//
|
||||||
|
// Notes:
|
||||||
|
// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant
|
||||||
|
// to make adopting hardening easier but should not be used outside of this scenario;
|
||||||
|
// - C++26 wording for Library Hardening precludes a conforming Hardened implementation from using the Contracts
|
||||||
|
// `ignore` semantic when evaluating hardened preconditions in the Library. Libc++ allows using this semantic for
|
||||||
|
// hardened preconditions, however, be aware that using `ignore` does not produce a conforming "Hardened"
|
||||||
|
// implementation, unlike the other semantics above.
|
||||||
|
// clang-format off
|
||||||
|
# define _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT (1 << 1)
|
||||||
|
# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 2)
|
||||||
|
# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 3)
|
||||||
|
# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 4)
|
||||||
|
# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 5)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
// If the user attempts to configure the assertion semantic, check that it is allowed in the current environment.
|
||||||
|
#if defined(_LIBCPP_ASSERTION_SEMANTIC)
|
||||||
|
# if !_LIBCPP_HAS_EXPERIMENTAL_LIBRARY
|
||||||
|
# error "Assertion semantics are an experimental feature."
|
||||||
|
# endif
|
||||||
|
# if defined(_LIBCPP_CXX03_LANG)
|
||||||
|
# error "Assertion semantics are not available in the C++03 mode."
|
||||||
|
# endif
|
||||||
|
#endif // defined(_LIBCPP_ASSERTION_SEMANTIC)
|
||||||
|
|
||||||
|
// User-provided semantic takes top priority -- don't override if set.
|
||||||
|
#ifndef _LIBCPP_ASSERTION_SEMANTIC
|
||||||
|
|
||||||
|
# ifndef _LIBCPP_ASSERTION_SEMANTIC_DEFAULT
|
||||||
|
# error _LIBCPP_ASSERTION_SEMANTIC_DEFAULT is not defined. This definition should be set at configuration time in \
|
||||||
|
the `__config_site` header, please make sure your installation of libc++ is not broken.
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if _LIBCPP_ASSERTION_SEMANTIC_DEFAULT != _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT
|
||||||
|
# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_DEFAULT
|
||||||
|
# else
|
||||||
|
# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
|
||||||
|
# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
|
||||||
|
# else
|
||||||
|
# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
|
||||||
|
# endif
|
||||||
|
# endif // _LIBCPP_ASSERTION_SEMANTIC_DEFAULT != _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT
|
||||||
|
|
||||||
|
#endif // #ifndef _LIBCPP_ASSERTION_SEMANTIC
|
||||||
|
|
||||||
|
// Finally, validate the selected semantic (in case the user tries setting it to an incorrect value):
|
||||||
|
#if _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_IGNORE && \
|
||||||
|
_LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_OBSERVE && \
|
||||||
|
_LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE && \
|
||||||
|
_LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
|
||||||
|
# error _LIBCPP_ASSERTION_SEMANTIC must be set to one of the following values: \
|
||||||
|
_LIBCPP_ASSERTION_SEMANTIC_IGNORE, \
|
||||||
|
_LIBCPP_ASSERTION_SEMANTIC_OBSERVE, \
|
||||||
|
_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE, \
|
||||||
|
_LIBCPP_ASSERTION_SEMANTIC_ENFORCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _LIBCPP___CONFIGURATION_HARDENING_H
|
||||||
@@ -18,6 +18,9 @@
|
|||||||
|
|
||||||
// NOLINTBEGIN(libcpp-cpp-version-check)
|
// NOLINTBEGIN(libcpp-cpp-version-check)
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
# if __cplusplus < 201103L
|
||||||
|
# define _LIBCPP_CXX03_LANG
|
||||||
|
# endif
|
||||||
# if __cplusplus <= 201103L
|
# if __cplusplus <= 201103L
|
||||||
# define _LIBCPP_STD_VER 11
|
# define _LIBCPP_STD_VER 11
|
||||||
# elif __cplusplus <= 201402L
|
# elif __cplusplus <= 201402L
|
||||||
|
|||||||
+9
-16
@@ -31,22 +31,15 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Need to detect which libc we're using if we're on Linux.
|
// Need to detect which libc we're using if we're on Linux.
|
||||||
#if defined(__linux__) || defined(__AMDGPU__) || defined(__NVPTX__)
|
#if (defined(__linux__) || defined(__AMDGPU__) || defined(__NVPTX__)) && __has_include(<features.h>)
|
||||||
# if __has_include(<features.h>)
|
# include <features.h>
|
||||||
# include <features.h>
|
# if defined(__GLIBC_PREREQ)
|
||||||
# if defined(__GLIBC_PREREQ)
|
# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b)
|
||||||
# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b)
|
# else
|
||||||
# else
|
# define _LIBCPP_GLIBC_PREREQ(a, b) 0
|
||||||
# define _LIBCPP_GLIBC_PREREQ(a, b) 0
|
# endif // defined(__GLIBC_PREREQ)
|
||||||
# endif // defined(__GLIBC_PREREQ)
|
#else
|
||||||
# endif
|
# define _LIBCPP_GLIBC_PREREQ(a, b) 0
|
||||||
#endif
|
|
||||||
|
|
||||||
// This is required in order for _NEWLIB_VERSION to be defined in places where we use it.
|
|
||||||
// TODO: We shouldn't be including arbitrarily-named headers from libc++ since this can break valid
|
|
||||||
// user code. Move code paths that need _NEWLIB_VERSION to another customization mechanism.
|
|
||||||
#if __has_include(<picolibc.h>)
|
|
||||||
# include <picolibc.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __BYTE_ORDER__
|
#ifndef __BYTE_ORDER__
|
||||||
|
|||||||
+9
-9
@@ -44,9 +44,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// [coroutine.handle.export.import], export/import
|
// [coroutine.handle.export.import], export/import
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
|
||||||
coroutine_handle __tmp;
|
coroutine_handle __tmp;
|
||||||
__tmp.__handle_ = __addr;
|
__tmp.__handle_ = __addr;
|
||||||
return __tmp;
|
return __tmp;
|
||||||
@@ -55,7 +55,7 @@ public:
|
|||||||
// [coroutine.handle.observers], observers
|
// [coroutine.handle.observers], observers
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; }
|
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; }
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI bool done() const {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool done() const {
|
||||||
_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines");
|
_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines");
|
||||||
return __builtin_coro_done(__handle_);
|
return __builtin_coro_done(__handle_);
|
||||||
}
|
}
|
||||||
@@ -100,7 +100,7 @@ public:
|
|||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr coroutine_handle(nullptr_t) noexcept {}
|
_LIBCPP_HIDE_FROM_ABI constexpr coroutine_handle(nullptr_t) noexcept {}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI static coroutine_handle from_promise(_Promise& __promise) {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static coroutine_handle from_promise(_Promise& __promise) {
|
||||||
using _RawPromise = __remove_cv_t<_Promise>;
|
using _RawPromise = __remove_cv_t<_Promise>;
|
||||||
coroutine_handle __tmp;
|
coroutine_handle __tmp;
|
||||||
__tmp.__handle_ =
|
__tmp.__handle_ =
|
||||||
@@ -114,9 +114,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// [coroutine.handle.export.import], export/import
|
// [coroutine.handle.export.import], export/import
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
|
||||||
coroutine_handle __tmp;
|
coroutine_handle __tmp;
|
||||||
__tmp.__handle_ = __addr;
|
__tmp.__handle_ = __addr;
|
||||||
return __tmp;
|
return __tmp;
|
||||||
@@ -130,7 +130,7 @@ public:
|
|||||||
// [coroutine.handle.observers], observers
|
// [coroutine.handle.observers], observers
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; }
|
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; }
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI bool done() const {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool done() const {
|
||||||
_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines");
|
_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines");
|
||||||
return __builtin_coro_done(__handle_);
|
return __builtin_coro_done(__handle_);
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// [coroutine.handle.promise], promise access
|
// [coroutine.handle.promise], promise access
|
||||||
_LIBCPP_HIDE_FROM_ABI _Promise& promise() const {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Promise& promise() const {
|
||||||
return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false));
|
return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ private:
|
|||||||
// [coroutine.handle.hash]
|
// [coroutine.handle.hash]
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
struct hash<coroutine_handle<_Tp>> {
|
struct hash<coroutine_handle<_Tp>> {
|
||||||
_LIBCPP_HIDE_FROM_ABI size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept {
|
||||||
return hash<void*>()(__v.address());
|
return hash<void*>()(__v.address());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+11
-13
@@ -20,8 +20,6 @@
|
|||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
# if __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC)
|
|
||||||
|
|
||||||
// [coroutine.noop]
|
// [coroutine.noop]
|
||||||
// [coroutine.promise.noop]
|
// [coroutine.promise.noop]
|
||||||
struct noop_coroutine_promise {};
|
struct noop_coroutine_promise {};
|
||||||
@@ -37,7 +35,7 @@ public:
|
|||||||
|
|
||||||
// [coroutine.handle.noop.observers], observers
|
// [coroutine.handle.noop.observers], observers
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return true; }
|
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return true; }
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr bool done() const noexcept { return false; }
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool done() const noexcept { return false; }
|
||||||
|
|
||||||
// [coroutine.handle.noop.resumption], resumption
|
// [coroutine.handle.noop.resumption], resumption
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr void operator()() const noexcept {}
|
_LIBCPP_HIDE_FROM_ABI constexpr void operator()() const noexcept {}
|
||||||
@@ -45,23 +43,23 @@ public:
|
|||||||
_LIBCPP_HIDE_FROM_ABI constexpr void destroy() const noexcept {}
|
_LIBCPP_HIDE_FROM_ABI constexpr void destroy() const noexcept {}
|
||||||
|
|
||||||
// [coroutine.handle.noop.promise], promise access
|
// [coroutine.handle.noop.promise], promise access
|
||||||
_LIBCPP_HIDE_FROM_ABI noop_coroutine_promise& promise() const noexcept {
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI noop_coroutine_promise& promise() const noexcept {
|
||||||
return *static_cast<noop_coroutine_promise*>(
|
return *static_cast<noop_coroutine_promise*>(
|
||||||
__builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false));
|
__builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
// [coroutine.handle.noop.address], address
|
// [coroutine.handle.noop.address], address
|
||||||
_LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
|
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
_LIBCPP_HIDE_FROM_ABI friend coroutine_handle<noop_coroutine_promise> noop_coroutine() noexcept;
|
_LIBCPP_HIDE_FROM_ABI friend coroutine_handle<noop_coroutine_promise> noop_coroutine() noexcept;
|
||||||
|
|
||||||
# if __has_builtin(__builtin_coro_noop)
|
# if __has_builtin(__builtin_coro_noop)
|
||||||
_LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept { this->__handle_ = __builtin_coro_noop(); }
|
_LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept { this->__handle_ = __builtin_coro_noop(); }
|
||||||
|
|
||||||
void* __handle_ = nullptr;
|
void* __handle_ = nullptr;
|
||||||
|
|
||||||
# elif defined(_LIBCPP_COMPILER_GCC)
|
# elif defined(_LIBCPP_COMPILER_GCC)
|
||||||
// GCC doesn't implement __builtin_coro_noop().
|
// GCC doesn't implement __builtin_coro_noop().
|
||||||
// Construct the coroutine frame manually instead.
|
// Construct the coroutine frame manually instead.
|
||||||
struct __noop_coroutine_frame_ty_ {
|
struct __noop_coroutine_frame_ty_ {
|
||||||
@@ -78,19 +76,19 @@ private:
|
|||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept = default;
|
_LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept = default;
|
||||||
|
|
||||||
# endif // __has_builtin(__builtin_coro_noop)
|
# endif // __has_builtin(__builtin_coro_noop)
|
||||||
};
|
};
|
||||||
|
|
||||||
using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
|
using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
|
||||||
|
|
||||||
# if defined(_LIBCPP_COMPILER_GCC)
|
# if defined(_LIBCPP_COMPILER_GCC)
|
||||||
inline noop_coroutine_handle::__noop_coroutine_frame_ty_ noop_coroutine_handle::__noop_coroutine_frame_{};
|
inline noop_coroutine_handle::__noop_coroutine_frame_ty_ noop_coroutine_handle::__noop_coroutine_frame_{};
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
// [coroutine.noop.coroutine]
|
// [coroutine.noop.coroutine]
|
||||||
inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); }
|
[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept {
|
||||||
|
return noop_coroutine_handle();
|
||||||
# endif // __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC)
|
}
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ template <class _RandomAccessIterator, class _Comp>
|
|||||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
||||||
__check_strict_weak_ordering_sorted(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
|
__check_strict_weak_ordering_sorted(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
|
||||||
#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
|
#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
|
||||||
using __diff_t = __iter_diff_t<_RandomAccessIterator>;
|
using __diff_t = __iterator_difference_type<_RandomAccessIterator>;
|
||||||
using _Comp_ref = __comp_ref_type<_Comp>;
|
using _Comp_ref = __comp_ref_type<_Comp>;
|
||||||
if (!__libcpp_is_constant_evaluated()) {
|
if (!__libcpp_is_constant_evaluated()) {
|
||||||
// Check if the range is actually sorted.
|
// Check if the range is actually sorted.
|
||||||
|
|||||||
+6
-4
@@ -48,13 +48,15 @@ public:
|
|||||||
__data_._DoFree = true;
|
__data_._DoFree = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
exception(exception const&) _NOEXCEPT {}
|
exception(exception const&) _NOEXCEPT : __data_() {}
|
||||||
|
|
||||||
exception& operator=(exception const&) _NOEXCEPT { return *this; }
|
exception& operator=(exception const&) _NOEXCEPT { return *this; }
|
||||||
|
|
||||||
virtual ~exception() _NOEXCEPT {}
|
virtual ~exception() _NOEXCEPT {}
|
||||||
|
|
||||||
virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; }
|
[[__nodiscard__]] virtual char const* what() const _NOEXCEPT {
|
||||||
|
return __data_._What ? __data_._What : "Unknown exception";
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
__std_exception_data __data_;
|
__std_exception_data __data_;
|
||||||
@@ -76,7 +78,7 @@ public:
|
|||||||
_LIBCPP_HIDE_FROM_ABI exception& operator=(const exception&) _NOEXCEPT = default;
|
_LIBCPP_HIDE_FROM_ABI exception& operator=(const exception&) _NOEXCEPT = default;
|
||||||
|
|
||||||
virtual ~exception() _NOEXCEPT;
|
virtual ~exception() _NOEXCEPT;
|
||||||
virtual const char* what() const _NOEXCEPT;
|
[[__nodiscard__]] virtual const char* what() const _NOEXCEPT;
|
||||||
};
|
};
|
||||||
|
|
||||||
class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception {
|
class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception {
|
||||||
@@ -85,7 +87,7 @@ public:
|
|||||||
_LIBCPP_HIDE_FROM_ABI bad_exception(const bad_exception&) _NOEXCEPT = default;
|
_LIBCPP_HIDE_FROM_ABI bad_exception(const bad_exception&) _NOEXCEPT = default;
|
||||||
_LIBCPP_HIDE_FROM_ABI bad_exception& operator=(const bad_exception&) _NOEXCEPT = default;
|
_LIBCPP_HIDE_FROM_ABI bad_exception& operator=(const bad_exception&) _NOEXCEPT = default;
|
||||||
~bad_exception() _NOEXCEPT override;
|
~bad_exception() _NOEXCEPT override;
|
||||||
const char* what() const _NOEXCEPT override;
|
[[__nodiscard__]] const char* what() const _NOEXCEPT override;
|
||||||
};
|
};
|
||||||
#endif // !_LIBCPP_ABI_VCRUNTIME
|
#endif // !_LIBCPP_ABI_VCRUNTIME
|
||||||
|
|
||||||
|
|||||||
+27
-5
@@ -11,18 +11,24 @@
|
|||||||
|
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <__cstddef/nullptr_t.h>
|
#include <__cstddef/nullptr_t.h>
|
||||||
|
#include <__cstddef/size_t.h>
|
||||||
#include <__exception/operations.h>
|
#include <__exception/operations.h>
|
||||||
#include <__memory/addressof.h>
|
#include <__memory/addressof.h>
|
||||||
#include <__memory/construct_at.h>
|
#include <__memory/construct_at.h>
|
||||||
#include <__type_traits/decay.h>
|
#include <__type_traits/decay.h>
|
||||||
#include <__type_traits/is_pointer.h>
|
#include <__type_traits/is_pointer.h>
|
||||||
#include <cstdlib>
|
#include <__utility/move.h>
|
||||||
|
#include <__utility/swap.h>
|
||||||
|
#include <__verbose_abort>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# pragma GCC system_header
|
# pragma GCC system_header
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
_LIBCPP_PUSH_MACROS
|
||||||
|
#include <__undef_macros>
|
||||||
|
|
||||||
#ifndef _LIBCPP_ABI_MICROSOFT
|
#ifndef _LIBCPP_ABI_MICROSOFT
|
||||||
|
|
||||||
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
|
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
|
||||||
@@ -30,7 +36,7 @@
|
|||||||
namespace __cxxabiv1 {
|
namespace __cxxabiv1 {
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
_LIBCPP_OVERRIDABLE_FUNC_VIS void* __cxa_allocate_exception(size_t) throw();
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void* __cxa_allocate_exception(std::size_t) throw();
|
||||||
_LIBCPP_OVERRIDABLE_FUNC_VIS void __cxa_free_exception(void*) throw();
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void __cxa_free_exception(void*) throw();
|
||||||
|
|
||||||
struct __cxa_exception;
|
struct __cxa_exception;
|
||||||
@@ -57,6 +63,8 @@ _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
|
|||||||
|
|
||||||
#ifndef _LIBCPP_ABI_MICROSOFT
|
#ifndef _LIBCPP_ABI_MICROSOFT
|
||||||
|
|
||||||
|
inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT;
|
||||||
|
|
||||||
class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
|
class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
|
||||||
void* __ptr_;
|
void* __ptr_;
|
||||||
|
|
||||||
@@ -67,15 +75,21 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// exception_ptr is basically a COW string so it is trivially relocatable.
|
// exception_ptr is basically a COW string so it is trivially relocatable.
|
||||||
// It is also replaceable because assignment has normal value semantics.
|
|
||||||
using __trivially_relocatable _LIBCPP_NODEBUG = exception_ptr;
|
using __trivially_relocatable _LIBCPP_NODEBUG = exception_ptr;
|
||||||
using __replaceable _LIBCPP_NODEBUG = exception_ptr;
|
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {}
|
_LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {}
|
||||||
_LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
|
_LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
|
||||||
|
|
||||||
exception_ptr(const exception_ptr&) _NOEXCEPT;
|
exception_ptr(const exception_ptr&) _NOEXCEPT;
|
||||||
|
_LIBCPP_HIDE_FROM_ABI exception_ptr(exception_ptr&& __other) _NOEXCEPT : __ptr_(__other.__ptr_) {
|
||||||
|
__other.__ptr_ = nullptr;
|
||||||
|
}
|
||||||
exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
|
exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
|
||||||
|
_LIBCPP_HIDE_FROM_ABI exception_ptr& operator=(exception_ptr&& __other) _NOEXCEPT {
|
||||||
|
exception_ptr __tmp(std::move(__other));
|
||||||
|
std::swap(__tmp, *this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
~exception_ptr() _NOEXCEPT;
|
~exception_ptr() _NOEXCEPT;
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_ != nullptr; }
|
_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_ != nullptr; }
|
||||||
@@ -88,10 +102,16 @@ public:
|
|||||||
return !(__x == __y);
|
return !(__x == __y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT;
|
||||||
|
|
||||||
friend _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
|
friend _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
|
||||||
friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
|
friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT {
|
||||||
|
std::swap(__x.__ptr_, __y.__ptr_);
|
||||||
|
}
|
||||||
|
|
||||||
# if _LIBCPP_HAS_EXCEPTIONS
|
# if _LIBCPP_HAS_EXCEPTIONS
|
||||||
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
|
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
|
||||||
template <class _Ep>
|
template <class _Ep>
|
||||||
@@ -153,7 +173,7 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
|
|||||||
# else // !_LIBCPP_HAS_EXCEPTIONS
|
# else // !_LIBCPP_HAS_EXCEPTIONS
|
||||||
template <class _Ep>
|
template <class _Ep>
|
||||||
_LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep) _NOEXCEPT {
|
_LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep) _NOEXCEPT {
|
||||||
std::abort();
|
_LIBCPP_VERBOSE_ABORT("make_exception_ptr was called in -fno-exceptions mode");
|
||||||
}
|
}
|
||||||
# endif // _LIBCPP_HAS_EXCEPTIONS
|
# endif // _LIBCPP_HAS_EXCEPTIONS
|
||||||
|
|
||||||
@@ -201,4 +221,6 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
|
|||||||
#endif // _LIBCPP_ABI_MICROSOFT
|
#endif // _LIBCPP_ABI_MICROSOFT
|
||||||
_LIBCPP_END_UNVERSIONED_NAMESPACE_STD
|
_LIBCPP_END_UNVERSIONED_NAMESPACE_STD
|
||||||
|
|
||||||
|
_LIBCPP_POP_MACROS
|
||||||
|
|
||||||
#endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
|
#endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
|
||||||
|
|||||||
+2
-2
@@ -40,7 +40,7 @@ public:
|
|||||||
|
|
||||||
// access functions
|
// access functions
|
||||||
[[__noreturn__]] void rethrow_nested() const;
|
[[__noreturn__]] void rethrow_nested() const;
|
||||||
_LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; }
|
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
@@ -73,7 +73,7 @@ template <class _Tp>
|
|||||||
__throw_with_nested<_Tp,
|
__throw_with_nested<_Tp,
|
||||||
_Up,
|
_Up,
|
||||||
is_class<_Up>::value && !is_base_of<nested_exception, _Up>::value &&
|
is_class<_Up>::value && !is_base_of<nested_exception, _Up>::value &&
|
||||||
!__libcpp_is_final<_Up>::value>::__do_throw(std::forward<_Tp>(__t));
|
!__is_final_v<_Up> >::__do_throw(std::forward<_Tp>(__t));
|
||||||
#else
|
#else
|
||||||
((void)__t);
|
((void)__t);
|
||||||
// FIXME: Make this abort
|
// FIXME: Make this abort
|
||||||
|
|||||||
+5
-5
@@ -20,22 +20,22 @@ _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
|
|||||||
defined(_LIBCPP_BUILDING_LIBRARY)
|
defined(_LIBCPP_BUILDING_LIBRARY)
|
||||||
using unexpected_handler = void (*)();
|
using unexpected_handler = void (*)();
|
||||||
_LIBCPP_EXPORTED_FROM_ABI unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
|
_LIBCPP_EXPORTED_FROM_ABI unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
|
||||||
_LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT;
|
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT;
|
||||||
[[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void unexpected();
|
[[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void unexpected();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using terminate_handler = void (*)();
|
using terminate_handler = void (*)();
|
||||||
_LIBCPP_EXPORTED_FROM_ABI terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
|
_LIBCPP_EXPORTED_FROM_ABI terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
|
||||||
_LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT;
|
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT;
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
|
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
|
||||||
_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT;
|
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT;
|
||||||
#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
|
#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
|
||||||
_LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT;
|
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT;
|
||||||
|
|
||||||
class _LIBCPP_EXPORTED_FROM_ABI exception_ptr;
|
class _LIBCPP_EXPORTED_FROM_ABI exception_ptr;
|
||||||
|
|
||||||
_LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
|
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
|
||||||
[[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
|
[[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
|
||||||
_LIBCPP_END_UNVERSIONED_NAMESPACE_STD
|
_LIBCPP_END_UNVERSIONED_NAMESPACE_STD
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user